Angular2 ไม่สามารถผูกกับ DIRECTIVE เนื่องจากไม่ใช่คุณสมบัติขององค์ประกอบที่เป็นที่รู้จัก


92

ฉันสร้าง @Directive ใหม่โดย Angular CLI มันถูกนำเข้ามาที่ app.module.ts ของฉัน

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

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

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

และฉันพยายามใช้ในส่วนประกอบของฉัน (ChatWindowComponent)

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

แม้ว่าภายในคำสั่งจะเป็นเพียงโค้ดที่สร้างขึ้น Angular CLI:

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

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

 constructor() { }

 }

ฉันได้รับข้อผิดพลาด:

zone.js: 388 การปฏิเสธสัญญาที่ไม่สามารถจัดการได้: ข้อผิดพลาดในการแยกวิเคราะห์เทมเพลต: ไม่สามารถเชื่อมโยงกับ 'appContenteditableModel' ได้เนื่องจากไม่ใช่คุณสมบัติที่เป็นที่รู้จักของ 'p'

ฉันลองเปลี่ยนแปลงเกือบทุกอย่างที่เป็นไปได้ตามเอกสารเชิงมุมนี้ทุกอย่างควรใช้งานได้ แต่ไม่ได้ผล

ความช่วยเหลือใด ๆ


ผลลัพธ์ที่ฉันต้องการคือ[(appContenteditableModel)]="draftMessage.text"ตอนท้าย ...
Tomas Javurek

แล้วลองแบบนี้<p [appContenteditableModel]="draftMessage.text"></p>
Sanket

มันใช้งานได้โดยไม่ต้องวงเล็บappContenteditableModel="draftMessage.text"และ(appContenteditableMode)l="draftMessage.text"แก้ปัญหาการปฏิเสธสัญญา แต่ดูเหมือนว่าจะไม่ผ่านตัวแปร
Tomas Javurek

คำตอบ:


147

เมื่อรวมคุณสมบัติไว้ในวงเล็บ[]คุณกำลังพยายามผูกเข้ากับคุณสมบัตินั้น ดังนั้นคุณต้องประกาศเป็น@Inputไฟล์.

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

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

  @Input()
  appContenteditableModel: string;

  constructor() { }

}

ส่วนที่สำคัญคือสมาชิก ( appContenteditableModel) ต้องถูกตั้งชื่อเป็นคุณสมบัติบนโหนด DOM (และในกรณีนี้คือตัวเลือกคำสั่ง)


ฉันมีอินพุต@Input ('appContenteditableModel') model : any;และเอาต์พุต @Output ('appContenteditableModel') update : EventEmitter<any> = new EventEmitter();ในคำสั่งของฉันด้วย ดูเหมือนว่าโมเดลจะทำงานได้ดี แต่ตัวปล่อยที่เรียกโดยthis.update.emit(value)ไม่เปลี่ยนค่าในองค์ประกอบหลัก ฉันทำอะไรผิด? [(appContenteditableModel)]="draftMessage.text"
Tomas Javurek

อันที่จริงฉันพยายาม "จำลอง" [(ngModel)] นอกองค์ประกอบ <input>
Tomas Javurek

@Outputมีไว้สำหรับการเปล่งเหตุการณ์เท่านั้น หากคุณต้องการให้ค่าตรงกันกับของผู้ปกครองคุณอาจพิจารณาเพิ่ม@HostBindingคำอธิบายประกอบ
naeramarth7

ถ้าฉันขีดเส้นใต้@HostBindingจะช่วยรักษาค่าให้ตรงกันภายในองค์ประกอบ html ฉันใช่ไหม องค์ประกอบนี้ฉันต้องได้รับการแก้ไขโดยผู้ใช้contenteditable="true"ดังนั้นอินพุตที่ฉันต้องซิงค์กับตัวแปรในส่วนประกอบเดียวกัน
Tomas Javurek

35

หากคุณใช้โมดูลที่ใช้ร่วมกันเพื่อกำหนดคำสั่งตรวจสอบให้แน่ใจว่าได้รับการประกาศและส่งออกโดยโมดูลที่กำหนดไว้

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

แล้วถ้าไม่อยู่ในโมดูลเดียวกันล่ะ?
Ohad Sadan

@OhadSadan ฉันไม่แน่ใจว่าคุณหมายถึงอะไร นี่คือตัวอย่างของเวลาที่คุณไม่มีในโมดูลเดียวกันและฉันแค่บอกว่าอย่าลืมประกาศและส่งออกคำสั่งถ้าคุณสร้างในโมดูลที่แชร์ (ซึ่งคุณต้องนำเข้าในโมดูล โมดูลที่แตกต่างกัน)
Simon_Weaver

ในโมดูล 'หลัก' ของคุณคุณจะต้องนำเข้า 'โมดูลคำสั่ง' เท่านั้นจากนั้นส่วนประกอบทั้งหมดของคุณจะสามารถมองเห็นได้
Simon_Weaver

นี่เป็นรายละเอียดนาที แต่พลาดบ่อย ขอบคุณ !
Sami

2

สำหรับผมการแก้ไขถูกย้ายอ้างอิงคำสั่งจากรากapp.module.ts(เส้นสำหรับimport, declarationsและ / หรือexports) เพื่อโมดูลเฉพาะเจาะจงมากขึ้นsrc/subapp/subapp.module.tsส่วนประกอบของฉันเป็น


1

กล่าวโดยสรุปเนื่องจากคำสั่งของคุณดูเหมือนคำสั่งจุดยึดให้ถอดวงเล็บออกและมันจะได้ผล

อันที่จริงฉันไม่พบส่วนที่เกี่ยวข้องที่เกี่ยวข้องกับเวลาที่ควรนำวงเล็บออกหรือไม่ซึ่งมีเพียงการกล่าวถึงเพียงครั้งเดียวที่ฉันพบเท่านั้นที่อยู่ในส่วนขององค์ประกอบไดนามิก :

นำไปใช้<ng-template> โดยไม่มีวงเล็บเหลี่ยม

ซึ่งไม่ครอบคลุมอย่างสมบูรณ์ในเอกสารAttribute Directives

ฉันเห็นด้วยกับคุณเป็นรายบุคคลและคิดว่า[appContenteditableModel]ควรจะเท่ากับappContenteditableModelและตัวแยกวิเคราะห์เทมเพลตเชิงมุมอาจแก้ไขได้ว่ามีการ@input()ผูกข้อมูลหรือไม่โดยอัตโนมัติเช่นกัน แต่ดูเหมือนว่าจะไม่ได้รับการประมวลผลอย่างเท่าเทียมกันภายใต้ประทุนแม้ใน Angular เวอร์ชันปัจจุบันที่ 7


1

ฉันประสบปัญหาเดียวกันกับคำสั่งที่ประกาศในโมดูลที่ใช้ร่วมกัน ฉันใช้คำสั่งนี้เพื่อปิดใช้งานการควบคุมแบบฟอร์ม

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

}

เพื่อให้ทำงานได้อย่างถูกต้องให้ประกาศและส่งออกคำสั่งในโมดูลที่ใช้ร่วมกัน (หรือโมดูลใด ๆ ที่คุณกำลังใช้)

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

ตอนนี้เราสามารถใช้คำสั่งนี้ในโมดูลใด ๆ ที่เรากำลังนำเข้าSharedModule

ตอนนี้เพื่อปิดการใช้งานการควบคุมของรูปแบบปฏิกิริยาเราสามารถใช้มันได้ดังนี้:

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

ฉันทำผิดพลาดฉันใช้เฉพาะตัวเลือก (appDisableControl) และส่งพารามิเตอร์ปิดการใช้งานไปยังสิ่งนี้ แต่ในการส่งพารามิเตอร์อินพุตเราต้องใช้มันเหมือนด้านบน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.