Я пишу пользовательскую директиву, чтобы перевести все поля формы в режим только для чтения / отключен Форма angular содержит другие пользовательские элементы формы, которые реализуют интерфейс ControlValueAccessor.
ComponentA. html
<form [customDir]="readonly" id="formA" #formA="ngForm">
<input type="text" id="name" name="name" [(ngModel)]="source.name" required>
<custom-comp #childComponent name="config" [(ngModel)]="source.config">
</custom-comp>
</form>
ComponentA.ts
export class ComponentA {
public readonly: boolean = true;
}
customComp. html
<fieldset [customDir]="readonly" id="custom-comp" ngForm="customComp" #customComp="ngForm">
<select name="data" [(ngModel)]="config.data" required>
<option *ngFor="let datapoint of datapoints" [value]="datapoint.id">{{ datapoint.name }}</option>
</select>
</fieldset>
customComp.ts
export class customComp implements ControlValueAccessor {
public config: {[key: string]: any} = {};
public readonly: boolean;
public writeValue(config: {[key: string]: any}): void {
this.config = config;
}
public registerOnChange(callback: any): void { }
public registerOnTouched(callback: any): void { }
}
CustomDirective.ts
@Directive({
selector: '[customDir]'
})
export class CustomDirective implements OnChanges {
@Input() customDir: boolean = false;
constructor(private ngForm: NgForm) {}
public ngOnChanges(changes: SimpleChanges) {
if (changes.readOnlyform.currentValue) {
this.makeReadonly();
}
}
private makeReadonly(): void {
let directives = this.ngForm['_directives']; // This returns the ngModel
for (let directive of directives) {
let valueAccessor = directive.valueAccessor;
let nativeElement = valueAccessor['_elementRef'].nativeElement;
let tagName: string = nativeElement.tagName;
if (tagName === 'SELECT' || tagName === 'TEXTAREA') {
nativeElement.setAttribute('disabled', true);
} else if (tagName === 'INPUT') {
if (nativeElement.type === 'checkbox') {
nativeElement.setAttribute('disabled', true);
}
nativeElement.setAttribute('readonly', true);
}
} else {
// In case of custom elements, thoe elements should have 'readonly' public property
valueAccessor.readonly = true;
}
}
Свойство _directives в ngForm является частным свойством. Будет ли это исключено в более поздних версиях Angular? Безопасно ли использовать эту частную собственность?
Или есть лучший способ реализовать мой сценарий использования? Есть ли другой способ доступа к ngModel?