Есть ли способ получить доступ к ngModel, связанному с формой в пользовательской директиве? За исключением частной собственности "_directives" - PullRequest
0 голосов
/ 07 февраля 2020

Я пишу пользовательскую директиву, чтобы перевести все поля формы в режим только для чтения / отключен Форма 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?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...