web-dev-qa-db-fra.com

Angular2 Impossible de se lier à DIRECTIVE car il ne s'agit pas d'une propriété connue de l'élément.

J'ai généré le nouveau @Directive par Angular CLI, il a été importé dans mon app.module.ts

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

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

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

et j'essaie d'utiliser dans mon composant (ChatWindowComponent)

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

même si la directive ne contient que du code angulaire généré par la CLI: 

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

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

 constructor() { }

 }

J'ai eu l'erreur: 

zone.js: 388 Rejet de la promesse non gérée: erreurs d'analyse de modèle: Impossible de se lier à 'appContenteditableModel' car ce n'est pas une propriété connue de 'p'.

J'ai essayé presque tous les changements possibles, en suivant cette documentation angulaire tout devrait fonctionner mais cela ne fonctionne pas. 

De l'aide?

50
Tomas Javurek

Lorsque vous mettez une propriété entre crochets [], vous essayez de vous y connecter. Donc, vous devez le déclarer comme un @Input.

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

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

  @Input()
  appContenteditableModel: string;

  constructor() { }

}

La partie importante est que le membre (appContenteditableModel) doit être nommé en tant que propriété du noeud DOM (et, dans ce cas, du sélecteur de directive).

87
naeramarth7

Si vous utilisez un module partagé pour définir la directive, assurez-vous qu'elle est déclarée et exportée par le module dans lequel elle est définie.

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

En résumé, comme votre directive ressemble à une directive d'ancre , supprimez les crochets et cela fonctionnerait.

En fait, je n'ai pas trouvé les sections correspondantes relatives au moment où les crochets doivent être supprimés ou non, où une seule mention trouvée se trouve dans la section sur composants dynamiques } _:

Appliquez cela à <ng-template> sans les crochets

, qui n’est cependant pas parfaitement couvert dans le document Attributes Directives .

Individuellement, je suis d’accord avec vous et je pensais que [appContenteditableModel] devrait être égal à appContenteditableModel et que l’analyseur de gabarit angulaire pourrait également déterminer s’il existe une liaison de données @input() ou non automatiquement. Mais ils ne semblent pas être traités de manière égale sous le capot, même dans les versions actuelles Angular Version of 7.

1
千木郷

Pour moi, le correctif consistait à déplacer les références de directive de la racine app.module.ts (les lignes pour import, declarations et/ou exports) vers le module plus spécifique src/subapp/subapp.module.ts auquel mon composant appartenait.

0
SushiGuy