无法绑定到'x',因为它不是'y'的已知属性

时间:2017-04-20 14:48:07

标签: angular typescript

我有一个角度站点,其中包含另一个组件内的组件。我正在使用路由和延迟加载外部组件(ComponentA)。内部组件(ComponentB)取决于第三方指令。

这是proof of concept(打开控制台查看错误)。

在ComponentB中使用第三方指令时出错。这不是指令本身的错误,而是我编写代码的错误。

<tree-root [nodes]="nodes"></tree-root>
  

无法绑定到'nodes',因为它不是'tree-root'的已知属性

我可以通过在ComponentA中导入第三方模块来解决此问题,但由于ComponentA不依赖于此模块,因此感觉不对。

我创建的Plunker只是我应用程序的一小部分,旨在隔离问题。这是为了展示一个概念,而不是作为一个应用程序有意义。我想要实现的是创建一个可以添加到我的任何页面的组件。此组件可以是小部件或其他内容,添加到一个或多个父页面。它是独立的。

我对Angular的有限知识开始在这里展示。由于组件应该允许我们进行基于组件的开发,将我们的应用程序分成更小的部分,我不明白为什么ComponentA需要知道ComponentB具有哪些依赖关系才能在其视图中使用它。

我还将证明这只是一个问题,因为我在ComponentB中包含了第三方指令。如果我删除该指令,一切正常。例如,如果我做了类似的事情:

<ul>
    <li *ngFor="let node of nodes">
        {{ node.name }}
    </li>
</ul>

该应用运行良好,没有任何错误。

我做错了什么,我应该做些什么?如果解决方案是向ComponentA添加导入,我会接受这个答案,因为提供了一个很好的解释(例如为什么*ngFor有效但tree-root指令没有)。

5 个答案:

答案 0 :(得分:36)

我回到起点并意识到我错过了什么:

feature-b.module.ts我应该导出组件:

exports: [
    FeatureBComponent
]

我还需要导入FeatureBModule而不是FeatureBComponent

从'../ feature-b / feature-b.component'导入{FeatureBComponent};

import { FeatureBModule } from '../feature-b/feature-b.module';

答案 1 :(得分:2)

我能够通过完全删除FeatureBModule来运行应用程序。然后FeatureAModule是正确的,因为它需要delcare FeatureBComponent。

然后,FeatureAModule看起来像这样:

import { NgModule }       from '@angular/core';
import { CommonModule }   from '@angular/common';

import { FeatureAComponent }           from './feature-a.component';
import { FeatureARoutingModule }       from './feature-a-routing.module';
import { TreeModule }                  from 'angular-tree-component';

import { FeatureBComponent } from '../feature-b/feature-b.component';

@NgModule({
  imports: [
    CommonModule,
    FeatureARoutingModule,
    TreeModule
  ],
  declarations: [
    FeatureAComponent,
    FeatureBComponent
  ]
})
export class FeatureAModule {}

我在这里更新了plunker:https://plnkr.co/edit/mkGH5uG1FGsWWpWbS1Zw?p=preview

答案 2 :(得分:2)

您在绑定到附加了指令本身的属性但指令的输入装饰不正确的属性的指令上会遇到此错误。

@Directive({ selector: '[myDirective]' })
export class MyDirective {
    @Input('mydirectiveSpelledDifferently') data: any;
}

示例中的输入具有"mydirectiveSpelledDifferently",但应与选择器匹配(即"myDirective")。

当您以这种方式工作时,您会知道这是问题所在

<div myDirective>

但是这种方式失败了:

<div [myDirective]="something">

工作案例是正确找到您为指令选择的选择器。失败的案例正在寻找@Input()装饰,但没有成功,因为它在您的指令中不以@Input('myDirective')的形式出现。

答案 3 :(得分:1)

我刚刚遇到了同样的情况,问题是我为该组件输入了错误的大小写('a'与'A')。

在父组件的模板中,我有:

<mychild-component></mychild-component>

代替

<myChild-component></myChild-component>

答案 4 :(得分:0)

与MMalke类似。默认情况下,当通过命令行界面生成组件时,Angular在组件的选择器名称中添加前缀app-。我应该写<app-my-component><app-my-component>,但我写<my-component><my-component>。仅供参考,请检查以确保组件的选择器名称与HTML中的名称匹配。