사용자 지정 요소에 ngModel을 구현하는 방법은 무엇입니까?
단순한 경우input
내가 할 수 있는 요소:
<input [(ngModel)]="name" /> {{ name }}
사용자 지정 요소에는 적합하지 않습니다.
<my-selfmade-combobox [(ngModel)]="name" values="getValues()" required></my-selfmade-combobox>
어떻게 구현할 수 있습니까?
[(ngModel)]="item"
의 줄임말입니다.[ngModel]="item" (ngModelChange)="item = $event"
즉, 예를 들어 2방향 바인딩 속성을 구성 요소에 추가하려는 경우
<app-my-control [(myProp)]="value"></app-my-control>
구성 요소에서 필요한 것은 추가하기만 하면 됩니다.
@Input()
myProp: string;
// Output prop name must be Input prop name + 'Change'
// Use in your component to write an updated value back out to the parent
@Output()
myPropChange = new EventEmitter<string>();
그@Input
쓰기를 처리하고 부모에게 새 값을 다시 쓰기 위해, 그냥 전화하세요.this.myPropChange.emit("Awesome")
값이 변경될 때마다 배출물이 업데이트되도록 하려면 해당 속성의 설정기에 배출물을 넣을 수 있습니다.
작동 방식/이유에 대한 자세한 설명은 여기를 참조하십시오.
이름을 사용하려는 경우ngModel
(왜냐하면 요소에 결합하는 추가 명령어가 있기 때문입니다.)ngModel
) 또는 이는 다음을 위한 것입니다.FormControl
구성요소가 아닌 요소(AKA, 사용을 위한ngForm
), 그러면 당신은 그것을 가지고 놀 필요가 있을 것입니다.ControlValueAccessor
자신만의 제품을 만들기 위한 자세한 설명FormControl
그리고 그것이 작동하는 이유는 여기에서 읽을 수 있습니다.
정말 필요하다면,[(ngModel)]
(지원)ngForm
,와는 달리[(myProp)]
접근), 이 링크가 귀하의 질문에 답할 것이라고 생각합니다.
이를 위해 다음 두 가지를 구현해야 합니다.
- 양식 구성 요소의 논리를 제공하는 구성 요소입니다.ngModel 자체에서 제공하기 때문에 입력이 필요하지 않습니다.
- 관습
ControlValueAccessor
이 구성 요소와 이 구성 요소 사이의 브리지를 구현할 것입니다.ngModel
/ngControl
이전 링크는 전체 샘플을 제공합니다.
다음을 구현했습니다.ngModel
공유 구성요소에 한 번만 입력하면 매우 간단하게 확장할 수 있습니다.
코드 두 줄만:
providers: [createCustomInputControlValueAccessor(MyInputComponent)]
extends InputComponent
my-input.component.ts
import { Component, Input } from '@angular/core';
import { InputComponent, createCustomInputControlValueAccessor } from '../../../shared/components/input.component';
@Component({
selector: 'my-input',
templateUrl: './my-input-component.component.html',
styleUrls: ['./my-input-component.scss'],
providers: [createCustomInputControlValueAccessor(MyInputComponent)]
})
export class MyInputComponent extends InputComponent {
@Input() model: string;
}
my-input.component.sys
<div class="my-input">
<input [(ngModel)]="model">
</div>
input.component.ts
import { Component, forwardRef, ViewChild, ElementRef, OnInit } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
export function createCustomInputControlValueAccessor(extendedInputComponent: any) {
return {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => extendedInputComponent),
multi: true
};
}
@Component({
template: ''
})
export class InputComponent implements ControlValueAccessor, OnInit {
@ViewChild('input') inputRef: ElementRef;
// The internal data model
public innerValue: any = '';
// Placeholders for the callbacks which are later provided
// by the Control Value Accessor
private onChangeCallback: any;
// implements ControlValueAccessor interface
writeValue(value: any) {
if (value !== this.innerValue) {
this.innerValue = value;
}
}
// implements ControlValueAccessor interface
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
// implements ControlValueAccessor interface - not used, used for touch input
registerOnTouched() { }
// change events from the textarea
private onChange() {
const input = <HTMLInputElement>this.inputRef.nativeElement;
// get value from text area
const newValue = input.value;
// update the form
this.onChangeCallback(newValue);
}
ngOnInit() {
const inputElement = <HTMLInputElement>this.inputRef.nativeElement;
inputElement.onchange = () => this.onChange();
inputElement.onkeyup = () => this.onChange();
}
}
1단계: 추가providers
아래 속성:
@Component({
selector: 'my-cool-element',
templateUrl: './MyCool.component.html',
styleUrls: ['./MyCool.component.css'],
providers: [{ // <================================================ ADD THIS
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MyCoolComponent),
multi: true
}]
})
2단계: 구현ControlValueAccessor
:
export class MyCoolComponent implements ControlValueAccessor {
private _value: string;
// Whatever name for this (myValue) you choose here, use it in the .html file.
public get myValue(): string { return this._value }
public set myValue(v: string) {
if (v !== this._value) {
this._value = v;
this.onChange(v);
}
}
constructor() {}
onChange = (_) => { };
onTouched = () => { };
writeValue(value: any): void {
this.myValue = value;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState?(isDisabled: boolean): void {
throw new Error("Method not implemented.");
}
}
3단계: html에서 원하는 컨트롤을 바인딩합니다.myValue
:
<my-cool-element [(value)]="myValue">
<!-- ..... -->
</my-cool-element>
사용자 정의 양방향 바인딩을 직접 구현할 수 있습니다.각도 10의 경우 공식 예제 SizerComponent를 참조하십시오. 여기서[(size)]
똑같이 행동합니다.[(ngModel)]
:
<app-sizer [(size)]="fontSizePx"></app-sizer>
언급URL : https://stackoverflow.com/questions/35149535/how-to-implement-ngmodel-on-custom-elements
'sourcetip' 카테고리의 다른 글
도커 파일에서 CMD와 엔트리 포인트의 차이점은 무엇입니까? (0) | 2023.09.05 |
---|---|
Pandas.append() 방법에 대한 좋은 대안은 이제 더 이상 사용되지 않습니다. (0) | 2023.09.05 |
Powershell 전자 메일 메시지 - 여러 수신자에게 보내는 전자 메일 (0) | 2023.09.05 |
MYSQL의 하위 쿼리에서 LIMIT 키워드를 사용하는 대신 (0) | 2023.09.05 |
SQL Create 문에서 명명된 외부 키 제약 조건 추가 (0) | 2023.09.05 |