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