Đầu vào tùy chỉnh angle2 rc.5, Không có trình truy cập giá trị cho điều khiển biểu mẫu với tên không xác định


80

Tôi có thành phần đầu vào tùy chỉnh đơn giản như thế này,

import {Component, Provider, forwardRef} from "@angular/core";
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from "@angular/forms";

const noop = () => {};

const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => CustomInputComponent),
  multi: true
};

@Component({
  selector: 'custom-input',
  template: `

          <input class="form-control" 
                 [(ngModel)]="value" name="somename"
                 (blur)="onTouched()">

  `,
  providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class CustomInputComponent implements ControlValueAccessor{

  //The internal data model
  private _value: any = '';

  //Placeholders for the callbacks
  private _onTouchedCallback: () => void = noop;

  private _onChangeCallback: (_:any) => void = noop;

  //get accessor
  get value(): any { return this._value; };

  //set accessor including call the onchange callback
  set value(v: any) {
    if (v !== this._value) {
      this._value = v;
      this._onChangeCallback(v);
    }
  }

  //Set touched on blur
  onTouched(){
    this._onTouchedCallback();
  }

  //From ControlValueAccessor interface
  writeValue(value: any) {
    this._value = value;
  }

  //From ControlValueAccessor interface
  registerOnChange(fn: any) {
    this._onChangeCallback = fn;
  }

  //From ControlValueAccessor interface
  registerOnTouched(fn: any) {
    this._onTouchedCallback = fn;
  }

}

và tôi có mô-đun ứng dụng như thế này,

/**
 * Created by amare on 8/15/16.
 */
import { NgModule }                     from '@angular/core';
import { BrowserModule }                from '@angular/platform-browser';
import { ReactiveFormsModule, FormsModule }          from '@angular/forms';
import { AppComponent }                 from './app/app.component';
import {CustomInputComponent} from "./app/shared/custom.input.component";
import {RouterModule} from "@angular/router";
@NgModule({
  imports: [ BrowserModule, ReactiveFormsModule, FormsModule, RouterModule ],
  declarations: [ AppComponent, CustomInputComponent],
  bootstrap: [ AppComponent ]
})
export class AppModule {  
}

và chính

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule }              from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

và tôi đã sử dụng đầu vào tùy chỉnh của mình trong một trong các thành phần của tôi như được hiển thị bên dưới, nhưng nhận được 'Không có trình truy cập giá trị cho điều khiển biểu mẫu với thuộc tính tên không xác định'.

<custom-input name="firstName" [(ngModel)]="firstName"></custom-input>

và app.component trông như thế này

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

@Component({
  moduleId: module.id,
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css']
})
export class AppComponent {
  title = 'app works!';

  firstName: string;
}

Tôi gặp vấn đề tương tự với một chỉ thị tùy chỉnh triển khai ControlValueAccessor. Nó đã hoạt động trong RC4 nhưng gặp lỗi giống như bạn đối với RC5. Hy vọng ai đó có một giải pháp.
user2444499

38
Thử thêm ngDefaultControlđể kiểm soát của bạn, như thế này:<custom-input name="firstName" [(ngModel)]="firstName" ngDefaultControl></custom-input>
danieleds

@danieleds cảm ơn rất nhiều vì nó hoạt động như một sự quyến rũ, mặc dù nhóm góc cạnh đã không phản hồi.
Amare

1
Hãy cẩn thận với bất kỳ gói nào của bên thứ 3 mà bạn có thể đang sử dụng - nếu bạn nhập bất kỳ gói nào đang sử dụng cũ FORM_DIRECTIVES, nó sẽ phá vỡ ứng dụng của bạn! Trường hợp điển hình: github.com/valor-software/ng2-charts/issues/352
Pete

Đối với tôi thêm ngDefaultControl trước [(ngModel)] = "...." làm việc
themightysapien

Câu trả lời:


73

thêm ngDefaultControl vào thành phần đầu vào tùy chỉnh trong máy chủ đã giải quyết được vấn đề, cảm ơn @danieleds


8
Giải pháp này đã không làm việc cho tôi. Tôi có một tên được áp dụng cho của mình inputvà tôi cũng đã thử thêm ngDefaultControlvào đầu vào nhưng nó không hoạt động. Vẫn cho tôi cùng một lỗi. Trong RC5
prolink007,

2
Đồng ý, tôi đã thêm thuộc tính tên trong html và ngDefaultControl và tôi sử dụng formControl và nó không hoạt động.
Steve K,

1
Xem giải thích rất hay về cách ngDefaultControlhoạt động - stackoverflow.com/a/46465959/968003 . Về cơ bản, nó thêm mặc định ControlValueAccessor, hoạt động như một cầu nối giữa API biểu mẫu Angular và một phần tử gốc trong DOM.
Alex Klaus,

46

Thêm ngDefaultControl vào thành phần đầu vào tùy chỉnh. Điều này bổ sung thêm tính năng kết hợp dữ liệu hai chiều, bạn không cần phải triển khai các phương thức của trình truy cập giá trị trừ khi bạn đang làm điều gì đó độc đáo.

<custom-input name="firstName" [(ngModel)]="firstName" ngDefaultControl></custom-input>

12

Thêm ngDefaultControlvào đầu vào của bạn. ví dụ

<inline-editor type="textarea" [(ngModel)]="editableTextArea" (onSave)="saveEditable($event)" value="valor" ngDefaultControl> </inline-editor> 

Sau đó import { FORM_DIRECTIVES } from '@angular/common';

Cuối cùng là chỉ thị: [FORM_DIRECTIVES]

Điều này sẽ hoạt động :) Cảm ơn các ý kiến ​​trên


2
Vui lòng sử dụng dấu nền và các markdownlệnh khác để làm cho bài đăng của bạn dễ đọc hơn.
buhtz

4
Tôi đang sử dụng RC6 và không có FORM_DIRECTIVEStrong@angular/common
Kosmonaft

6
HƯỚNG DẪN MẪU KHÔNG CÓ HƠN NG2 CUỐI CÙNG
Steve K

4

Tôi đã gắn thẻ [(ngModel)]của mình <option>thay vì<select>

Vì vậy, yeah ... điều đó sẽ gây ra điều này.


Yup .... Tôi cũng gặp lỗi tương tự khi đặt ngModel trên <mat-radio-button>, chứ không phải <mat-radio-group>. Grrrrrr ....
Mike Gledhill

0

Như một tình huống khác xuất hiện, tôi đã [(ngModel)]chỉ định một thành phần tùy chỉnh gần đây đã được xây dựng lại và đơn giản hóa, và phiên bản mới của thành phần chỉ có ngModelnhư một biến đầu vào bình thường với các lần phát.

Điều này là không đủ - biến đầu vào phải được đổi tên thành một cái gì đó bên cạnh ngModel, hoặc thành phần phải triển khai ControlValueAccessorgiao diện ( xem tài liệu để biết chi tiết ). Sau khi hoàn tất cái này hay cái kia, bạn sẽ không còn gặp lỗi này nữa.

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.