如何在Angular2 Typescript中更改HTML元素readonly和required属性?

And*_*uze 25 typescript angular

对于我的一些组件,我想改变输入字段readonly和来回的必需属性.

我已经设法获得一个正在运行的代码,它可以根据需要更改它们,但问题是它只适用于readonly,但似乎没有按要求工作:虽然元素属性更改为所需的Angular2仍然认为fieldCtrl是有效的.

这是我的plunker,我在这里说明了这个问题:https://plnkr.co/edit/Yq2RDzUJjLPgReIgSBAO?p = preview

//our root app component
import {Component} from 'angular2/core'

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div>
    <form #f="ngForm">
      <button type="button" (click)="toggleReadOnly()">Change readonly!</button>
      <button type="button" (click)="toggleRequired()">Change required!</button>
      <input id="field" [(ngModel)]="field" ngControl="fieldCtrl" #fieldCtrl="ngForm"/>
      {{fieldCtrl.valid}}
    </form>
    </div>
  `,
  directives: []
})
export class App {
  constructor() {
    this.name = 'Angular2'
  }

  toggleRequired(){
    this.isRequired = !this.isRequired;
    var fieldElement = <HTMLInputElement>document.getElementById('field');
    if (this.isRequired){
      fieldElement.required = true;
      this.field = "it's required now";
    }
    else{
      fieldElement.required = false;
      this.field = "can leave it blank";
    }
  }

  toggleReadOnly(){
    this.isReadOnly = !this.isReadOnly;
    var fieldElement = <HTMLInputElement>document.getElementById('field');
    if (this.isReadOnly){
      fieldElement.readOnly = true;
      this.field = "it's readonly now";
    }
    else{
      fieldElement.readOnly = false;
      this.field = "feel free to edit";
    }
  }

  private isReadOnly:boolean=false;

  private field:string = "feel free to edit";

  private isRequired:boolean=false;

}
Run Code Online (Sandbox Code Playgroud)

更新:尝试建议的方法

[required]="isRequired" [readonly]="isReadOnly"
Run Code Online (Sandbox Code Playgroud)

它就像readonly的魅力一样,并且对于required = true,但我不能再关闭所需的属性 - 它显示空字段无效,尽管不再需要.

更新的plunker:https://plnkr.co/edit/6LvMqFzXHaLlV8fHbdOE

UPDATE2:尝试建议的方法

[required]="isRequired ? true : null"
Run Code Online (Sandbox Code Playgroud)

它确实逐个元素地添加/删除所需的属性,但是对于不需要的空字段,字段控制器的有效属性显示为false.

在Angular2 Typescript中更改所需属性的正确方法是什么?

Gün*_*uer 34

对于要删除的绑定属性,需要将它们设置为null.有一个讨论要改变它以删除,但它被拒绝,至少现在.

 [required]="isRequired ? '' : null"
Run Code Online (Sandbox Code Playgroud)

要么

 [required]="isRequired ? 'required' : null"
Run Code Online (Sandbox Code Playgroud)

你的Plunker会因为[]身边缺失而产生错误ngControl.

有关工作示例,请参见此Plunker

另见Deilan的评论如下.


pix*_*its 5

您似乎已经有了添加/删除readonly属性的答案.对于required属性,我建议创建一个服务来跟踪验证器的启用/禁用状态,然后在绑定到验证控件时利用该服务.

州验证员

该类负责跟踪验证器及其启用/禁用状态.

export class StateValidator {
    public enabled: boolean = true;
    validator: (control: Control) => { [key: string]: boolean };
    constructor(validator: (control: Control) => 
        { [key: string]: boolean }, enabled: boolean) {
        this.enabled = enabled;
        this.validator = validator;

    }

    enable() {
        this.enabled = true;
    }
    disable() {
        this.enabled = false;
    }
    toggle() {
        this.enabled = !this.enabled;
    }
    get() {
        return (control: Control) => {
            if (this.enabled)
                return this.validator(control);
            return null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它具有启用,禁用或切换验证器的方法; 还有一个get返回新验证器函数的方法,如果启用验证器,调用时将调用底层验证器函数,或者在未启用验证器时返回null.

验证服务

此类是一个单例服务,负责按键注册验证器,以及支持基于该密钥启用,禁用或切换验证器的方法.

export class ValidationService {
    validators: { [key: string]: StateValidator } = {};
    register(key: string, validator: Function): Function {
        var stateValidator = new StateValidator(<(control: Control) => { [key: string]: boolean }>validator, true);
        this.validators[key] = stateValidator;
        return stateValidator.get();
    }
    enable(key: string) {
        this.validators[key].enable();
    }
    disable(key: string) {
        this.validators[key].disable();
    }
    toggle(key: string) {
        this.validators[key].toggle();
    }
    list() {
        var l = [];
        for (var key in this.validators) {
            if (this.validators.hasOwnProperty(key)) {
                l.push({ key: key, value: this.validators[key].enabled });
            }
        }
        return l;
    }
}
Run Code Online (Sandbox Code Playgroud)

该服务还具有list返回键/值对列表的功能,其中键表示注册的验证器键,并且该值是表示验证器的启用状态的布尔指示符.

零件

要使用ValidationService,请在引导期间使用根注入器注册服务:

bootstrap(AppComponent, [ValidationService]);
Run Code Online (Sandbox Code Playgroud)

或者使用组件级注入器注册服务:

@Component({
  selector: 'app',
  providers: [ValidationService],
  ...
})
Run Code Online (Sandbox Code Playgroud)

然后在组件的构造函数中注入服务:

export class AppComponent {
    form: ControlGroup;
    constructor(public validationService:ValidationService) {
      ...
    }
}
Run Code Online (Sandbox Code Playgroud)

接下来,像往常一样绑定到验证控件,除了使用ValidationServiceto注册并返回状态验证器:

new Control('', validationService.register('required', Validators.required));
Run Code Online (Sandbox Code Playgroud)

此解决方案的一大优点是,您可以轻松地将状态验证器与其他内置或自定义验证器进行组合和混合:

this.form = new ControlGroup({
    name: new Control('hello',
        Validators.compose([
            validationService.register('required', Validators.required),
            validationService.register('minlength', Validators.minLength(4)),
            Validators.maxLength(10)]))

});
Run Code Online (Sandbox Code Playgroud)

切换验证器

使用该服务切换验证器的状态:

validationService.toggle('required');
Run Code Online (Sandbox Code Playgroud)

下面是一个如何绑定到表中的状态验证器列表,并将toggle函数连接到按钮单击事件的示例:

<table>
  <tr>
     <td>Validator</td>
     <td>Is Enabled?</td>
     <td></td>
  </tr>
  <tr *ngFor="#v of validationService.list()">
     <td>{{v.key}}</td>
     <td>{{v.value }}</td>
     <td><button (click)="validationService.toggle(v.key)">Toggle</button></td>
  </tr>
</table>
Run Code Online (Sandbox Code Playgroud)

演示Plnkr

在此输入图像描述