Angular2, elemanın bilinen bir özelliği olmadığı için DIRECTIVE'e bağlanamaz


92

Angular CLI tarafından yeni @Directive oluşturdum, onu app.module.ts'ime aktarıldı

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

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

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

ve bileşenimde kullanmaya çalışıyorum (ChatWindowComponent)

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

direktif içinde sadece Angular CLI tarafından üretilen kod olsa bile:

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

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

 constructor() { }

 }

Hatayı aldım:

zone.js: 388 İşlenmemiş Söz reddi: Şablon ayrıştırma hataları: "p" nin bilinen bir özelliği olmadığı için "appContenteditableModel" e bağlanılamıyor.

Bu açısal belgeleri takiben hemen hemen her olası değişikliği denedim, her şey çalışmalı ama olmuyor.

Herhangi bir yardım?


İhtiyacım olan sonuç [(appContenteditableModel)]="draftMessage.text"sonunda ...
Tomas Javurek

Öyleyse böyle deneyin<p [appContenteditableModel]="draftMessage.text"></p>
Sanket

Parantez olmadan çalışır appContenteditableModel="draftMessage.text"ve aynı zamanda (appContenteditableMode)l="draftMessage.text"vaat reddini çözer, ancak aynı zamanda değişkeni geçmiyor gibi görünüyor
Tomas Javurek

Yanıtlar:


147

Bir özelliği parantez içine []alırken ona bağlamaya çalışıyorsunuz. Yani bunu bir @Input.

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

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

  @Input()
  appContenteditableModel: string;

  constructor() { }

}

Önemli olan, üye ( appContenteditableModel) 'nin DOM düğümündeki özellik (ve bu durumda, yönerge seçicisi) olarak adlandırılması gerektiğidir.


Yönergemde girdi @Input ('appContenteditableModel') model : any;ve çıktı var @Output ('appContenteditableModel') update : EventEmitter<any> = new EventEmitter();. Görünüşe göre model iyi çalışıyor ancak tarafından çağrılan yayıcı this.update.emit(value), ana bileşendeki değeri değiştirmiyor. Neyi yanlış yapıyorum? [(appContenteditableModel)]="draftMessage.text"
Tomas Javurek

Aslında <input> öğesinin dışında [(ngModel)] "simüle etmeye" çalışıyorum
Tomas Javurek

@Outputyalnızca olayları yaymak içindir. Değeri ebeveynin değeriyle senkronize tutmak istiyorsanız, @HostBindingek açıklama eklemeyi düşünebilirsiniz .
naeramarth7

İyi anlarsam @HostBinding, değerin html öğesi içinde uyumlu kalmasına yardımcı olur, haklı mıyım? Bu eleman contenteditable="true", girdinin aynı bileşendeki değişkenle senkronize kalması için kullanıcı tarafından düzenlenmem gerekiyor.
Tomas Javurek

35

Yönergeyi tanımlamak için paylaşılan bir modül kullanıyorsanız, bunun içinde tanımlandığı modül tarafından hem bildirildiğinden hem de dışa aktarıldığından emin olun.

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

ve ya aynı modülde değillerse?
Ohad Sadan

@OhadSadan Ne demek istediğinizden tam olarak emin değilim. Bu, aynı modülde olmadığınız durumlara bir örnektir ve direktifleri paylaşılan bir modülde oluşturuyorsanız (daha sonra bunları bir farklı modül).
Simon_Weaver

"Ana" modülünüzde yalnızca "yönerge modülünü" içe aktarmanız gerekir ve ardından tüm bileşenleriniz onları görebilir.
Simon_Weaver

Bu küçük bir ayrıntıdır, ancak çoğu zaman gözden kaçar. Teşekkür ederim !
Sami

2

Benim için düzeltme, yönerge referanslarını kökten taşımaktı app.module.ts (çizgiler için import, declarationsve / veya exportsdaha spesifik modülüne) src/subapp/subapp.module.tsbenim bileşeni aitti.


1

Özetle, direktifiniz bir çapa direktifine benzediği için , köşeli parantezleri kaldırın ve işe yarayacaktır.

Aslında, parantezlerin ne zaman kaldırılması gerektiğiyle ilgili ilgili bölümleri bulamadım, burada dinamik bileşenlerle ilgili bölümde bulduğum tek bir söz var :

Bunu köşeli parantezler olmadan uygulayın<ng-template>

, ancak bu, Nitelik Direktiflerinde tam olarak kapsanmamaktadır belgesinde .

Bireysel olarak, sizinle aynı fikirdeyim ve [appContenteditableModel]bunun eşit olması gerektiğini düşünüyordum appContenteditableModelve açısal şablon ayrıştırıcı, @input()veri bağlamanın otomatik olarak olup olmadığı konusunda da işe yarayabilir . Ancak, mevcut 7'nin Angular Versiyonunda bile, tam olarak başlık altında eşit olarak işlenmemiş gibi görünüyorlar.


1

Paylaşılan bir modülde açıklanan bir yönerge ile aynı sorunla karşılaşıyordum. Bir form denetimini devre dışı bırakmak için bu yönergeyi kullanıyorum.

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]();
  }

}

Düzgün çalışması için, yönergeyi paylaşılan modülde (veya kullandığınız herhangi bir modülde) açıklayın ve dışa aktarın.

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 { }

Artık bu yönergeyi SharedModule'u içe aktardığımız her modülde kullanabiliriz .

Şimdi reaktif bir formun kontrolünü devre dışı bırakmak için bunu şu şekilde kullanabiliriz:

<input type="text" class="form-control" name="userName" formControlName="userName" appDisableControl [disableControl]="disable" />

Hata yapıyordum, sadece seçici (appDisableControl) kullanıyordum ve devre dışı bırakma parametresini buna geçiriyordum. ancak bir girdi parametresini geçmek için yukarıdaki gibi kullanmalıyız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.