वास्तव में, लागू करने के लिए दो चीजें हैं:
- एक घटक जो आपके प्रपत्र घटक का तर्क प्रदान करता है। यह एक इनपुट नहीं है क्योंकि यह
ngModelस्वयं द्वारा प्रदान किया जाएगा
- एक रिवाज
ControlValueAccessorजो इस घटक और ngModel/ के बीच पुल को लागू करेगाngControl
चलो एक नमूना लेते हैं। मैं एक घटक को लागू करना चाहता हूं जो किसी कंपनी के लिए टैग की सूची का प्रबंधन करता है। घटक टैग जोड़ने और हटाने की अनुमति देगा। मैं यह सुनिश्चित करने के लिए एक सत्यापन जोड़ना चाहता हूं कि टैग सूची खाली नहीं है। मैं नीचे वर्णित के रूप में इसे अपने घटक में परिभाषित करूंगा:
(...)
import {TagsComponent} from './app.tags.ngform';
import {TagsValueAccessor} from './app.tags.ngform.accessor';
function notEmpty(control) {
if(control.value == null || control.value.length===0) {
return {
notEmpty: true
}
}
return null;
}
@Component({
selector: 'company-details',
directives: [ FormFieldComponent, TagsComponent, TagsValueAccessor ],
template: `
<form [ngFormModel]="companyForm">
Name: <input [(ngModel)]="company.name"
[ngFormControl]="companyForm.controls.name"/>
Tags: <tags [(ngModel)]="company.tags"
[ngFormControl]="companyForm.controls.tags"></tags>
</form>
`
})
export class DetailsComponent implements OnInit {
constructor(_builder:FormBuilder) {
this.company = new Company('companyid',
'some name', [ 'tag1', 'tag2' ]);
this.companyForm = _builder.group({
name: ['', Validators.required],
tags: ['', notEmpty]
});
}
}
TagsComponentघटक जोड़ सकते हैं और में तत्वों को दूर करने के तर्क को परिभाषित करता है tagsसूची।
@Component({
selector: 'tags',
template: `
<div *ngIf="tags">
<span *ngFor="#tag of tags" style="font-size:14px"
class="label label-default" (click)="removeTag(tag)">
{{label}} <span class="glyphicon glyphicon-remove"
aria- hidden="true"></span>
</span>
<span> | </span>
<span style="display:inline-block;">
<input [(ngModel)]="tagToAdd"
style="width: 50px; font-size: 14px;" class="custom"/>
<em class="glyphicon glyphicon-ok" aria-hidden="true"
(click)="addTag(tagToAdd)"></em>
</span>
</div>
`
})
export class TagsComponent {
@Output()
tagsChange: EventEmitter;
constructor() {
this.tagsChange = new EventEmitter();
}
setValue(value) {
this.tags = value;
}
removeLabel(tag:string) {
var index = this.tags.indexOf(tag, 0);
if (index != undefined) {
this.tags.splice(index, 1);
this.tagsChange.emit(this.tags);
}
}
addLabel(label:string) {
this.tags.push(this.tagToAdd);
this.tagsChange.emit(this.tags);
this.tagToAdd = '';
}
}
जैसा कि आप देख सकते हैं, इस घटक में कोई इनपुट नहीं है, लेकिन setValueएक (नाम यहाँ महत्वपूर्ण नहीं है)। हम ngModelघटक से मूल्य प्रदान करने के लिए बाद में इसका उपयोग करते हैं। यह घटक घटक की स्थिति (टैग सूची) अद्यतन होने पर सूचित करने के लिए एक घटना को परिभाषित करता है।
आइए अब इस घटक और ngModel/ के बीच की कड़ी को लागू करें ngControl। यह एक निर्देश के अनुरूप है जो ControlValueAccessorइंटरफ़ेस को लागू करता है। एक प्रदाता को NG_VALUE_ACCESSORटोकन के खिलाफ इस मूल्य अभिगमकर्ता के लिए परिभाषित किया जाना चाहिए ( forwardRefनिर्देश के बाद परिभाषित होने के बाद से उपयोग करना न भूलें )।
निर्देश tagsChangeहोस्ट की घटना पर एक ईवेंट श्रोता संलग्न करेगा (यानी वह घटक जो निर्देश पर संलग्न है, अर्थात TagsComponent)। onChangeजब घटना होती विधि बुलाया जाएगा। यह विधि Angular2 द्वारा पंजीकृत एक से मेल खाती है। इस तरह यह संबंधित प्रपत्र नियंत्रण के अनुसार परिवर्तनों और अद्यतनों से अवगत होगा।
writeValueजब में बंधे मूल्य कहा जाता है ngFormअद्यतन किया जाता है। (अर्थात TagsComponent) पर संलग्न घटक को इंजेक्ट करने के बाद, हम इसे इस मान को पास करने में सक्षम होंगे (पिछली setValueविधि देखें )।
CUSTOM_VALUE_ACCESSORनिर्देश के बाइंडिंग में प्रदान करने के लिए मत भूलना ।
यहाँ कस्टम का पूरा कोड है ControlValueAccessor:
import {TagsComponent} from './app.tags.ngform';
const CUSTOM_VALUE_ACCESSOR = CONST_EXPR(new Provider(
NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => TagsValueAccessor), multi: true}));
@Directive({
selector: 'tags',
host: {'(tagsChange)': 'onChange($event)'},
providers: [CUSTOM_VALUE_ACCESSOR]
})
export class TagsValueAccessor implements ControlValueAccessor {
onChange = (_) => {};
onTouched = () => {};
constructor(private host: TagsComponent) { }
writeValue(value: any): void {
this.host.setValue(value);
}
registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
}
इस तरह जब मैं tagsकंपनी के सभी को हटा देता हूं , validतो companyForm.controls.tagsनियंत्रण की विशेषता falseस्वतः हो जाती है ।
अधिक विवरण के लिए यह लेख (अनुभाग "NgModel- संगत घटक") देखें: