J'ai généré une nouvelle @Directive par Angular CLI, elle a été importée 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'essaye d'utiliser dans mon composant (ChatWindowComponent)
<p [appContenteditableModel] >
Write message
</p>
même si la directive contient uniquement du code généré par CLI angulaire:
import { Directive } from '@angular/core';
@Directive({
selector: '[appContenteditableModel]'
})
export class ContenteditableModelDirective {
constructor() { }
}
J'ai eu l'erreur:
zone.js: 388 Rejet de promesses non gérées: 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 ce n'est pas le cas.
De l'aide?
angular
typescript
directive
Tomas Javurek
la source
la source
[(appContenteditableModel)]="draftMessage.text"
à la fin ...<p [appContenteditableModel]="draftMessage.text"></p>
appContenteditableModel="draftMessage.text"
et(appContenteditableMode)l="draftMessage.text"
résout également le rejet de la promesse, mais il semble également ne pas passer la variableRéponses:
Lorsque vous encapsulez une propriété entre crochets,
[]
vous essayez de vous y lier. Vous devez donc le déclarer comme un fichier@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é comme propriété sur le nœud DOM (et, dans ce cas, le sélecteur de directive).la source
@Input ('appContenteditableModel') model : any;
et une sortie@Output ('appContenteditableModel') update : EventEmitter<any> = new EventEmitter();
dans ma directive. Il semble que le modèle fonctionne bien mais l'émetteur appelé parthis.update.emit(value)
ne change pas la valeur du composant parent. Ce que je fais mal?[(appContenteditableModel)]="draftMessage.text"
@Output
est pour l'émission d'événements uniquement. Si vous souhaitez garder la valeur synchronisée avec celle du parent, vous pouvez envisager d'ajouter l'@HostBinding
annotation.@HostBinding
cela aidera à garder la valeur synchronisée dans l'élément html, ai-je raison? Cet élément doit être modifié par l'utilisateurcontenteditable="true"
pour que l'entrée soit synchronisée avec la variable du même composant.Si vous utilisez un module partagé pour définir la directive, assurez-vous qu'elle est à la fois 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] })
la source
Pour moi , le correctif se déplaçait les références directive de la racine
app.module.ts
(les lignes pourimport
,declarations
et / ouexports
) au module plus spécifiquesrc/subapp/subapp.module.ts
mon composant appartenait.la source
En résumé, comme votre directive ressemble à une directive d'ancrage , supprimez les crochets et cela fonctionnerait.
En fait, je n'ai pas trouvé les sections correspondantes liées au moment où les crochets doivent être supprimés ou non, où une seule mention que j'ai trouvée se trouve dans la section sur les composants dynamiques :
, qui n'est cependant pas parfaitement couvert dans les directives d'attributs document des .
Individuellement, je suis d'accord avec vous et je pensais que cela
[appContenteditableModel]
devrait être égal àappContenteditableModel
et que l'analyseur de modèle angulaire pourrait également contourner le fait qu'il y ait@input()
une liaison de données ou non automatiquement. Mais ils semblent ne pas être traités de la même manière sous le capot, même dans la version angulaire actuelle de 7.la source
J'étais confronté au même problème avec une directive déclarée dans un module partagé. J'utilise cette directive pour désactiver un contrôle de formulaire.
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](); } }
Pour le faire fonctionner correctement, déclarez et exportez la directive dans le module partagé (ou dans tout module que vous utilisez).
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 { }
Nous pouvons maintenant utiliser cette directive dans n'importe quel module où nous importons SharedModule .
Maintenant, pour désactiver le contrôle d'un formulaire réactif, nous pouvons l'utiliser comme ceci:
<input type="text" class="form-control" name="userName" formControlName="userName" appDisableControl [disableControl]="disable" />
Erreur que je faisais, j'utilisais uniquement le sélecteur (appDisableControl) et en passant le paramètre de désactivation à cela. mais pour passer un paramètre d'entrée, nous devons l'utiliser comme ci-dessus.
la source