আসলে বাস্তবায়নের জন্য দুটি জিনিস রয়েছে:
- এমন একটি উপাদান যা আপনার ফর্মের উপাদানটির যুক্তি সরবরাহ করে। এটি কোনও ইনপুট লাগবে না কারণ এটি
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আপডেট করা হয়। সংযুক্ত উপাদানটি (যেমন ট্যাগসম্পোক্তর) সংযুক্ত করার পরে, আমরা এই মানটি পাস করার জন্য এটি কল করতে সক্ষম হবো (পূর্ববর্তী 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।
আরও তথ্যের জন্য এই নিবন্ধটি (বিভাগ "এনজিএমডেল-সামঞ্জস্যপূর্ণ উপাদান") দেখুন: