Eu gerei um novo @Directive pelo Angular CLI, ele foi importado para o meu app.module.ts
import { ContenteditableModelDirective } from './directives/contenteditable-model.directive';
import { ChatWindowComponent } from './chat-window/chat-window.component';
@NgModule({
declarations: [
AppComponent,
ContenteditableModelDirective,
ChatWindowComponent,
...
],
imports: [
...
],
...
})
e tento usar no meu componente (ChatWindowComponent)
<p [appContenteditableModel] >
Write message
</p>
mesmo se dentro da diretiva for apenas o código angular CLI gerado:
import { Directive } from '@angular/core';
@Directive({
selector: '[appContenteditableModel]'
})
export class ContenteditableModelDirective {
constructor() { }
}
Eu entendi o erro:
zone.js: 388 Rejeição de promessa não tratada: Erros de análise de modelo: Não é possível vincular a 'appContenteditableModel', pois não é uma propriedade conhecida de 'p'.
Eu tentei quase todas as mudanças possíveis, seguindo esta documentação angular tudo deveria funcionar, mas não funciona.
Qualquer ajuda?
angular
typescript
directive
Tomas Javurek
fonte
fonte
[(appContenteditableModel)]="draftMessage.text"
no final ...<p [appContenteditableModel]="draftMessage.text"></p>
appContenteditableModel="draftMessage.text"
e também(appContenteditableMode)l="draftMessage.text"
resolve a rejeição de promessa, mas também parece não passar a variávelRespostas:
Ao envolver uma propriedade entre colchetes,
[]
você está tentando vinculá-la. Portanto, você deve declará-lo como um@Input
.import { Directive, Input } from '@angular/core'; @Directive({ selector: '[appContenteditableModel]' }) export class ContenteditableModelDirective { @Input() appContenteditableModel: string; constructor() { } }
A parte importante é que o membro (
appContenteditableModel
) precisa ser nomeado como a propriedade no nó DOM (e, neste caso, o seletor de diretiva).fonte
@Input ('appContenteditableModel') model : any;
e saída@Output ('appContenteditableModel') update : EventEmitter<any> = new EventEmitter();
na minha diretiva. Parece que o modelo funciona bem, mas o emissor chamado porthis.update.emit(value)
não altera o valor do componente pai. O que eu faço de errado?[(appContenteditableModel)]="draftMessage.text"
@Output
serve apenas para emitir eventos. Se você deseja manter o valor sincronizado com o valor do pai, considere adicionar a@HostBinding
anotação.@HostBinding
ajudará a manter o valor em sincronia dentro do elemento html, estou certo? Este elemento preciso ser editado pelo usuáriocontenteditable="true"
para que a entrada que eu preciso manter em sincronia com a variável no mesmo componente.Se você estiver usando um módulo compartilhado para definir a diretiva, certifique-se de que ela seja declarada e exportada pelo módulo em que foi definida.
// this is the SHARED module, where you're defining directives to use elsewhere @NgModule({ imports: [ CommonModule ], declarations: [NgIfEmptyDirective, SmartImageDirective], exports: [NgIfEmptyDirective, SmartImageDirective] })
fonte
Para mim, a correção foi mover as referências da directiva de raiz
app.module.ts
(as linhas paraimport
,declarations
e / ouexports
) para o módulo mais específicasrc/subapp/subapp.module.ts
meu componente pertencia.fonte
Eu estava enfrentando o mesmo problema com uma diretiva declarada em um módulo compartilhado. Estou usando esta diretiva para desabilitar um controle de formulário.
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](); } }
Para funcionar corretamente, declare e exporte a diretiva no módulo compartilhado (ou qualquer módulo que você estiver usando).
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 { }
Agora podemos usar esta diretiva em qualquer módulo onde estivermos importando SharedModule .
Agora, para desativar o controle de uma forma reativa, podemos usá-lo assim:
<input type="text" class="form-control" name="userName" formControlName="userName" appDisableControl [disableControl]="disable" />
Erro eu estava fazendo isso, estava usando apenas o seletor (appDisableControl) e passando o parâmetro de desativação para este. mas para passar um parâmetro de entrada, temos que usá-lo como acima.
fonte
Em suma, como sua diretiva se parece com uma diretiva âncora , remova os colchetes e ela funcionaria.
Na verdade, não encontrei as seções correspondentes relacionadas a quando os colchetes devem ser removidos ou não, onde apenas uma menção que encontrei está localizada na seção sobre componentes dinâmicos :
, que, no entanto, não está perfeitamente coberto no documento de Diretivas de Atributos .
Individualmente, concordo com você e estava pensando que
[appContenteditableModel]
deveria ser igual aappContenteditableModel
e o analisador de modelo angular também pode solucionar se há@input()
vinculação de dados ou não automaticamente. Mas eles parecem exatamente não processados igualmente sob o capô, mesmo na versão Angular atual do 7.fonte