错误:无法解析指令的所有参数 [英] Error: Can't resolve all parameters for Directive

查看:84
本文介绍了错误:无法解析指令的所有参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试创建指令npm包时遇到问题.

I'm facing a problem trying to create a directive npm package.

我已经为@Component创建了软件包,但这是我为@Directive创建的第一个软件包.

I had already created packages for @Component but this is the first I create for @Directive.

我面临的问题是,当我运行 ng serve 时,构建就可以了,但是当我加载页面时,我得到了 Error:无法解析HighlightDirective的所有参数.

The problem I'm facing is that when I run ng serve the build completes ok but when I load the page I get the Error: Can't resolve all parameters for HighlightDirective.

奇怪的是,如果运行 ng服务--aot ,问题就不会出现.

The curious thing is that if a run ng serve --aot the problem does not appear.

因此,该程序包仅与--AOT一起使用,并与JIT一起引发错误.

So, the package works only with --AOT and throw error with JIT.

可能是--AOT在解析我的自定义指令之前包含了一些必需的软件包.在JIT中尝试在另一个模块加载所需的包之前加载指令的情况不会发生.

May be that --AOT is including some needed package before parsing my custom directive. It does not happen in JIT that try to load the directive before another module loads the needed package.

我做了个小问题来显示问题,我离开了程序包URL,以便您可以看到我的代码.

I made a plunker to show the problem and I'm leaving the package URL so you can see my code.

textarea-resize.directive.ts

textarea-resize.directive.ts

import { Directive, ElementRef, Input } from '@angular/core';

@Directive({ selector: 'textarea[textarea-resize]' })
export class HighlightDirective {
    constructor(el: ElementRef) {
       el.nativeElement.style.backgroundColor = 'yellow';
    }
}

Ps.指令名称现在是 HighlightDirective ,甚至是文件名 textarea-resize.directive ,因为我已经用angular.io docs中的指令替换了我的指令,以确保指令sintax是正确的.

Ps. The directive name is now HighlightDirective even being the file name textarea-resize.directive because I've replaced my directive with one from angular.io docs to be sure the directive sintax is correct.

我还测试了直接从我的应用而不是从node_module加载指令,这样,在AOT和JIT中一切正常.

I've also tested loading the directive directly from my app instead from node_module and this way everything works fine in both AOT and JIT.

感谢所有人的帮助.

UMD:柱塞: https://plnkr.co/edit/omWp7OfFvaoTQgG0Xs48?p=preview

包装: https://www.npmjs.com/package/@ neoprospecta/angular-textarea-resize

这是我用来构建的任务:

This is the task I use to build:

#!/usr/bin/env node
'use strict';

const fs = require('fs');
const path = require('path');
const glob = require('glob');

/**
 * Simple Promiseify function that takes a Node API and return a version that supports promises.
 * We use promises instead of synchronized functions to make the process less I/O bound and
 * faster. It also simplify the code.
 */
function promiseify(fn) {
  return function() {
    const args = [].slice.call(arguments, 0);
    return new Promise((resolve, reject) => {
      fn.apply(this, args.concat([function (err, value) {
        if (err) {
          reject(err);
        } else {
          resolve(value);
        }
      }]));
    });
  };
}

const readFile = promiseify(fs.readFile);
const writeFile = promiseify(fs.writeFile);
const outputDir = './inline-src';


function rmDir(dirPath) {
  try { var files = fs.readdirSync(dirPath); }
  catch(e) { return; }
  if (files.length > 0)
    for (var i = 0; i < files.length; i++) {
      var filePath = dirPath + '/' + files[i];
      if (fs.statSync(filePath).isFile())
        fs.unlinkSync(filePath);
      else
        rmDir(filePath);
    }
  fs.rmdirSync(dirPath);
};

function inlineResources(globs) {
  if (typeof globs == 'string') {
    globs = [globs];
  }

  /**
   * For every argument, inline the templates and styles under it and write the new file.
   */
  return Promise.all(globs.map(pattern => {
    if (pattern.indexOf('*') < 0) {
      // Argument is a directory target, add glob patterns to include every files.
      pattern = path.join(pattern, '**', '*');
    }

    const files = glob.sync(pattern, {})
      .filter(name => /\.ts$/.test(name));  // Matches only JavaScript files.

    rmDir(outputDir+'');
    fs.mkdir(outputDir);

    // Generate all files content with inlined templates.
    return Promise.all(files.map(filePath => {
      return readFile(filePath, 'utf-8')
        .then(content => inlineResourcesFromString(content, url => {
          return path.join(path.dirname(filePath), url);
        }))
        .then(content => {
          var inlinePath = outputDir +  '/' + filePath.replace(/^.*[\\\/]/, '')
          writeFile(inlinePath, content);
        })
        .catch(err => {
          console.error('An error occurred: ', err);
        });
    }));
  }));
}

/**
 * Inline resources from a string content.
 * @param content {string} The source file's content.
 * @param urlResolver {Function} A resolver that takes a URL and return a path.
 * @returns {string} The content with resources inlined.
 */
function inlineResourcesFromString(content, urlResolver) {
  // Curry through the inlining functions.
  return [
    inlineTemplate,
    inlineStyle,
    removeModuleId
  ].reduce((content, fn) => fn(content, urlResolver), content);
}

if (require.main === module) {
  inlineResources(process.argv.slice(2));
}


/**
 * Inline the templates for a source file. Simply search for instances of `templateUrl: ...` and
 * replace with `template: ...` (with the content of the file included).
 * @param content {string} The source file's content.
 * @param urlResolver {Function} A resolver that takes a URL and return a path.
 * @return {string} The content with all templates inlined.
 */
function inlineTemplate(content, urlResolver) {
  return content.replace(/templateUrl:\s*'([^']+?\.html)'/g, function(m, templateUrl) {
    const templateFile = urlResolver(templateUrl);
    const templateContent = fs.readFileSync(templateFile, 'utf-8');
    const shortenedTemplate = templateContent
      .replace(/([\n\r]\s*)+/gm, ' ')
      .replace(/"/g, '\\"');
    return `template: "${shortenedTemplate}"`;
  });
}


/**
 * Inline the styles for a source file. Simply search for instances of `styleUrls: [...]` and
 * replace with `styles: [...]` (with the content of the file included).
 * @param urlResolver {Function} A resolver that takes a URL and return a path.
 * @param content {string} The source file's content.
 * @return {string} The content with all styles inlined.
 */
function inlineStyle(content, urlResolver) {
  return content.replace(/styleUrls:\s*(\[[\s\S]*?\])/gm, function(m, styleUrls) {
    const urls = eval(styleUrls);
    return 'styles: ['
      + urls.map(styleUrl => {
          const styleFile = urlResolver(styleUrl);
          const styleContent = fs.readFileSync(styleFile, 'utf-8');
          const shortenedStyle = styleContent
            .replace(/([\n\r]\s*)+/gm, ' ')
            .replace(/"/g, '\\"');
          return `"${shortenedStyle}"`;
        })
        .join(',\n')
      + ']';
  });
}


/**
 * Remove every mention of `moduleId: module.id`.
 * @param content {string} The source file's content.
 * @returns {string} The content with all moduleId: mentions removed.
 */
function removeModuleId(content) {
  return content.replace(/\s*moduleId:\s*module\.id\s*,?\s*/gm, '');
}


module.exports = inlineResources;
module.exports.inlineResourcesFromString = inlineResourcesFromString;

推荐答案

我怀疑您忘记了

"emitDecoratorMetadata": true 

您的 tsconfig.json

这篇关于错误:无法解析指令的所有参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆