Angular2 无法绑定到 DIRECTIVE,因为它不是元素的已知 属性
Angular2 Can't bind to DIRECTIVE since it isn't a known property of element
我通过 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 未处理的承诺拒绝:模板解析错误:
无法绑定到 'appContenteditableModel',因为它不是 'p' 的已知 属性。
我尝试了几乎所有可能的更改,在此之后 angular docs 一切都应该有效,但没有。
有什么帮助吗?
将 属性 括在方括号 []
中时,您正试图绑定到它。所以你必须将它声明为 @Input
.
import { Directive, Input } from '@angular/core';
@Directive({
selector: '[appContenteditableModel]'
})
export class ContenteditableModelDirective {
@Input()
appContenteditableModel: string;
constructor() { }
}
重要的部分是,成员 (appContenteditableModel
) 需要在 DOM 节点上命名为 属性(在本例中,指令选择器) .
如果您使用共享模块来定义指令,请确保它由定义它的模块声明并导出。
// this is the SHARED module, where you're defining directives to use elsewhere
@NgModule({
imports: [
CommonModule
],
declarations: [NgIfEmptyDirective, SmartImageDirective],
exports: [NgIfEmptyDirective, SmartImageDirective]
})
对我来说,修复是将指令引用从根 app.module.ts
(import
、declarations
、and/or exports
的行)移动到更具体的模块 src/subapp/subapp.module.ts
我的组件属于。
总之,因为你的指令看起来像一个 anchor directive,去掉括号就可以了。
实际上,我没有找到与何时应该删除括号相关的相应部分,其中我找到的只有一个提及位于 dynamic components:
的部分
Apply that to <ng-template>
without the square brackets
,但在 Attribute Directives 文档中并未完全涵盖。
个人而言,我同意你的看法并且认为 [appContenteditableModel]
应该等于 appContenteditableModel
并且 angular 模板解析器可能会解决是否存在 @input()
数据绑定或者也不是自动的。但它们在幕后似乎并没有得到同样的处理,即使在当前的 Angular 7.
版本中也是如此
我在共享模块中声明的指令遇到了同样的问题。我正在使用此指令来禁用表单控件。
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" />
我做错了,我只使用选择器 (appDisableControl) 并将禁用参数传递给它。但是要传递一个输入参数,我们必须像上面那样使用它。
我通过 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 未处理的承诺拒绝:模板解析错误: 无法绑定到 'appContenteditableModel',因为它不是 'p' 的已知 属性。
我尝试了几乎所有可能的更改,在此之后 angular docs 一切都应该有效,但没有。
有什么帮助吗?
将 属性 括在方括号 []
中时,您正试图绑定到它。所以你必须将它声明为 @Input
.
import { Directive, Input } from '@angular/core';
@Directive({
selector: '[appContenteditableModel]'
})
export class ContenteditableModelDirective {
@Input()
appContenteditableModel: string;
constructor() { }
}
重要的部分是,成员 (appContenteditableModel
) 需要在 DOM 节点上命名为 属性(在本例中,指令选择器) .
如果您使用共享模块来定义指令,请确保它由定义它的模块声明并导出。
// this is the SHARED module, where you're defining directives to use elsewhere
@NgModule({
imports: [
CommonModule
],
declarations: [NgIfEmptyDirective, SmartImageDirective],
exports: [NgIfEmptyDirective, SmartImageDirective]
})
对我来说,修复是将指令引用从根 app.module.ts
(import
、declarations
、and/or exports
的行)移动到更具体的模块 src/subapp/subapp.module.ts
我的组件属于。
总之,因为你的指令看起来像一个 anchor directive,去掉括号就可以了。
实际上,我没有找到与何时应该删除括号相关的相应部分,其中我找到的只有一个提及位于 dynamic components:
的部分Apply that to
<ng-template>
without the square brackets
,但在 Attribute Directives 文档中并未完全涵盖。
个人而言,我同意你的看法并且认为 [appContenteditableModel]
应该等于 appContenteditableModel
并且 angular 模板解析器可能会解决是否存在 @input()
数据绑定或者也不是自动的。但它们在幕后似乎并没有得到同样的处理,即使在当前的 Angular 7.
我在共享模块中声明的指令遇到了同样的问题。我正在使用此指令来禁用表单控件。
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" />
我做错了,我只使用选择器 (appDisableControl) 并将禁用参数传递给它。但是要传递一个输入参数,我们必须像上面那样使用它。