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.