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

Tom*_*rek 72 directive typescript angular

我通过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: [
    ...
  ],
  ...
})
Run Code Online (Sandbox Code Playgroud)

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

<p [appContenteditableModel] >
    Write message
</p>
Run Code Online (Sandbox Code Playgroud)

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

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

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

 constructor() { }

 }
Run Code Online (Sandbox Code Playgroud)

我收到了错误:

zone.js:388未处理的Promise拒绝:模板解析错误:无法绑定到'appContenteditableModel',因为它不是'p'的已知属性.

我尝试了几乎所有可能的更改,遵循这个有角度的文档,一切都应该工作,但它没有.

有帮助吗?

nae*_*th7 114

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

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

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

  @Input()
  appContenteditableModel: string;

  constructor() { }

}
Run Code Online (Sandbox Code Playgroud)

重要的是,member(appContenteditableModel)需要被命名为DOM节点上的属性(在本例中,是指令选择器).

  • 啊谢谢你。万一其他人遇到它,我的具体问题是指令选择器(例如“selector:'fooDirective'”)与“@Input()”属性名称(例如“@Input()barDirective”)不匹配。我重命名了选择器,但也没有考虑该属性。 (3认同)

Sim*_*ver 25

如果您正在使用共享模块来定义指令,请确保它是由模块声明和导出的.

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


ImF*_*had 11

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

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]();
  }

}
Run Code Online (Sandbox Code Playgroud)

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

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 { }
Run Code Online (Sandbox Code Playgroud)

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

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

<input type="text" class="form-control" name="userName" formControlName="userName" appDisableControl [disableControl]="disable" />
Run Code Online (Sandbox Code Playgroud)

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


Sus*_*Guy 6

对我来说,解决方法是将指令引用从根( 、和/或 的app.module.ts行)移动到我的组件所属的更具体的模块。importdeclarationsexportssrc/subapp/subapp.module.ts