Angular2不能绑定到DIRECTIVE,因为它不是元素的已知属性

时间:2016-11-20 15:28:41

标签: angular typescript directive

我通过Angular CLI生成了新的@Directive,它被导入到我的app.module.ts

import { ContenteditableModelDirective } from './directives/contenteditable-model.directive';

import { ChatWindowComponent } from './chat-window/chat-window.component';

@NgModule({
  declarations: [
    AppComponent,
    ContenteditableModelDirective,
    ChatWindowComponent,
    ...
  ],
  imports: [
    ...
  ],
  ...
})

我尝试在我的组件中使用(ChatWindowComponent)

<p [appContenteditableModel] >
    Write message
</p>

即使在指令内只有Angular CLI生成的代码:

 import { Directive } from '@angular/core';

 @Directive({
   selector: '[appContenteditableModel]'
 })
 export class ContenteditableModelDirective {

 constructor() { }

 }

我收到了错误:

zone.js:388未处理承诺拒绝:模板解析错误: 无法绑定到&#39; appContenteditableModel&#39;因为它不是&#39;

的已知属性。

我尝试了几乎所有可能的更改,遵循此angular docs一切都应该有效,但事实并非如此。

任何帮助?

5 个答案:

答案 0 :(得分:94)

在括号[]中包装属性时,您尝试绑定它。所以你必须将它声明为@Input

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

@Directive({
 selector: '[appContenteditableModel]'
})
export class ContenteditableModelDirective {

  @Input()
  appContenteditableModel: string;

  constructor() { }

}

重要的是,成员(appContenteditableModel)需要被命名为DOM节点上的属性(在这种情况下,指令选择器)。

答案 1 :(得分:12)

如果您使用共享模块来定义指令,请确保该指令由定义在其中的模块声明和导出。

// this is the SHARED module, where you're defining directives to use elsewhere
@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [NgIfEmptyDirective, SmartImageDirective],
  exports: [NgIfEmptyDirective, SmartImageDirective]
})

答案 2 :(得分:2)

我在共享模块中声明的指令也遇到了同样的问题。我正在使用此指令禁用表单控件。

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

@Directive({
  selector: '[appDisableControl]'
})
export class DisableControlDirective {

  constructor(private ngControl: NgControl) { }

  @Input('disableControl') set disableControl( condition: boolean) {
    const action = condition ? 'disable' : 'enable';
    this.ngControl.control[action]();
  }

}

要使其正常工作,请在共享模块(或您使用的任何模块)中声明并导出指令。

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DisableControlDirective } from './directives/disable-control/disable-control.directive';

@NgModule({
  declarations: [
    DisableControlDirective
  ],
  imports: [
    CommonModule
  ],
  exports: [DisableControlDirective],
  providers: [],
  bootstrap: []
})
export class SharedModule { }

现在,我们可以在导入 SharedModule 的任何模块中使用此指令。

现在要禁用反应形式的控件,我们可以像这样使用它:

<input type="text" class="form-control" name="userName" formControlName="userName" appDisableControl [disableControl]="disable" />

Mistake我正在这样做,我只使用选择器(appDisableControl)并将禁用参数传递给它。但是要传递输入参数,我们必须像上面一样使用它。

答案 3 :(得分:1)

总而言之,由于您的指令看起来像anchor directive,因此删除括号即可。

实际上,我还没有找到与何时应该删除括号有关的相应部分,在dynamic components的部分中仅找到了我提到的内容:

  

将其应用于<ng-template> 不带方括号

,但是在Attribute Directives文档中并没有完全涵盖。

我个人也同意,并且认为[appContenteditableModel]应该等于appContenteditableModel,并且角度模板解析器也可能会自动解决是否存在@input()数据绑定。但是,即使在当前的Angular版本7中,它们似乎也无法在后台进行同样的处理。

答案 4 :(得分:0)

对我来说,解决方法是将指令引用从根app.module.tsimportdeclarations和/或exports的行)移到更具体的模块{ {1}}我的组件属于。