Angular2 không thể liên kết với DIRECTIVE vì nó không phải là một thuộc tính đã biết của phần tử


91

Tôi đã tạo @Directive mới bằng Angular CLI, nó đã được nhập vào app.module.ts của tôi

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

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

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

và tôi cố gắng sử dụng trong thành phần của mình (ChatWindowComponent)

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

ngay cả khi trong chỉ thị chỉ là mã được tạo Angular CLI:

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

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

 constructor() { }

 }

Tôi gặp lỗi:

zone.js: 388 Từ chối Promise chưa được xử lý: Lỗi phân tích cú pháp mẫu: Không thể liên kết với 'appContentitableModel' vì nó không phải là thuộc tính đã biết của 'p'.

Tôi đã thử hầu hết mọi thay đổi có thể, làm theo tài liệu góc cạnh này, mọi thứ sẽ hoạt động nhưng không.

Bất kỳ giúp đỡ?


Kết quả tôi cần là [(appContenteditableModel)]="draftMessage.text"lúc kết thúc ...
Tomas Javurek

Sau đó thử như thế này<p [appContenteditableModel]="draftMessage.text"></p>
Sanket

Nó hoạt động mà không cần dấu ngoặc appContenteditableModel="draftMessage.text"và cũng (appContenteditableMode)l="draftMessage.text"giải quyết từ chối lời hứa nhưng nó cũng dường như không vượt qua biến
Tomas Javurek

Câu trả lời:


146

Khi gói một thuộc tính trong dấu ngoặc, []bạn đang cố liên kết với nó. Vì vậy, bạn phải khai báo nó như là một @Input.

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

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

  @Input()
  appContenteditableModel: string;

  constructor() { }

}

Phần quan trọng là thành viên ( appContenteditableModel) cần được đặt tên là thuộc tính trên nút DOM (và trong trường hợp này là bộ chọn chỉ thị).


Tôi có đầu vào @Input ('appContenteditableModel') model : any;và đầu ra @Output ('appContenteditableModel') update : EventEmitter<any> = new EventEmitter();trong chỉ thị của mình. Có vẻ như mô hình hoạt động tốt nhưng bộ phát được gọi bởi this.update.emit(value)không thay đổi giá trị trong thành phần mẹ. Tôi làm gì sai? [(appContenteditableModel)]="draftMessage.text"
Tomas Javurek

Thật sự tôi cố gắng "mô phỏng" [(ngModel)] ngoài <input> yếu tố
Tomas Javurek

@Outputchỉ dành cho các sự kiện phát ra. Nếu bạn muốn giữ giá trị đồng bộ với giá trị gốc, bạn có thể xem xét thêm @HostBindingchú thích.
naeramarth

Nếu tôi gạch dưới và tốt @HostBindingsẽ giúp giữ giá trị đồng bộ trong phần tử html, tôi có đúng không? Phần tử này tôi cần được người dùng chỉnh sửa contenteditable="true"để đầu vào tôi cần giữ đồng bộ với biến trong cùng một thành phần.
Tomas Javurek

35

Nếu bạn đang sử dụng mô-đun chia sẻ để xác định chỉ thị, hãy đảm bảo rằng nó được khai báo và xuất theo mô-đun mà nó được định nghĩa trong đó.

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

và nếu chúng không ở trong cùng một mô-đun thì sao?
Ohad Sadan

@OhadSadan Tôi không chắc chính xác ý của bạn. Đây là một ví dụ về khi bạn không có chúng trong cùng một mô-đun và tôi chỉ nói rằng hãy đảm bảo khai báo VÀ xuất lệnh nếu bạn đang tạo chúng trong một mô-đun được chia sẻ (sau đó bạn phải nhập chúng vào một mô-đun khác nhau).
Simon_Weaver

Trong mô-đun 'chính' của bạn, bạn chỉ cần nhập 'mô-đun chỉ thị' và sau đó tất cả các thành phần của bạn có thể nhìn thấy chúng.
Simon_Weaver

Đây là một chi tiết nhỏ nhưng thường bị bỏ sót. Cảm ơn bạn !
Sami

2

Đối với tôi việc sửa chữa đã được di chuyển tài liệu tham khảo chỉ thị từ gốc app.module.ts(các dòng cho import, declarationsvà / hoặc exports) để các module cụ thể hơn src/subapp/subapp.module.tsthành phần của tôi thuộc về.


1

Tóm lại, bởi vì chỉ thị của bạn trông giống như một chỉ thị neo , hãy xóa dấu ngoặc và nó sẽ hoạt động.

Trên thực tế, tôi chưa tìm thấy các phần tương ứng liên quan đến thời điểm có nên xóa dấu ngoặc hay không, nơi chỉ có một đề cập mà tôi đã tìm thấy nằm ở phần về thành phần động :

Áp dụng điều đó cho <ng-template> không có dấu ngoặc vuông

, tuy nhiên không được đề cập hoàn hảo trong tài liệu Chỉ thị thuộc tính .

Về cá nhân, tôi đồng ý với bạn và nghĩ rằng điều đó [appContenteditableModel]phải bằng appContenteditableModelvà trình phân tích cú pháp mẫu góc cạnh cũng có thể hoạt động cho dù có @input()ràng buộc dữ liệu hay không tự động. Nhưng chúng dường như không được xử lý một cách chính xác như nhau, ngay cả trong phiên bản Angular 7 hiện tại.


1

Tôi đang gặp phải vấn đề tương tự với một chỉ thị được khai báo trong một mô-đun được chia sẻ. Tôi đang sử dụng lệnh này để tắt điều khiển biểu mẫu.

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

}

Để hoạt động bình thường, hãy khai báo và xuất chỉ thị trong mô-đun được chia sẻ (hoặc bất kỳ mô-đun nào bạn đang sử dụng).

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

Bây giờ chúng ta có thể sử dụng chỉ thị này trong bất kỳ mô-đun nào mà chúng ta đang nhập SharedModule .

Bây giờ để vô hiệu hóa điều khiển của biểu mẫu phản ứng, chúng ta có thể sử dụng nó như sau:

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

Tôi đã làm sai, tôi chỉ sử dụng bộ chọn (appDisableControl) và chuyển tham số vô hiệu hóa cho điều này. nhưng để vượt qua một tham số đầu vào, chúng ta phải sử dụng nó như trên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.