角度形式禁用对valueChanges

时间:2017-04-18 18:26:05

标签: javascript angular

我正在尝试在我的某个表单组值更改时禁用表单控件,但问题是方法disable()enable()也更新了表单状态,因此我有一个无限循环。

@Component({
  selector: 'my-app',
  template: `
   <form [formGroup]="questionForm">

     <input type="text" formControlName="question" />

     <input type="text" formControlName="other"/>
   </form>
  `,
})
export class App {

  constructor(private fb: FormBuilder) {  
     this.questionForm = this.fb.group({
       question: [''],
       other: ['']
     });
  }

  ngOnInit() {
     this.questionForm.valueChanges.subscribe(v => {
       if(v.question === 'test') {
         this.questionForm.get('other').disable();
       } else {
          ...enable()
       }
     })
  }

}

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:2)

嗯,根据official docs,您可以使用指令进行自定义验证,当然,在您的情况下,这可以应用于检查用户输入内容的逻辑,然后禁用并启用其他字段。那里有很多代码,sooooo ......

...如果你不想要所有这些代码,你也可以做一个小的黑客攻击。让我们调用一个函数来检查用户键入的内容。我们还需要绑定this,因此我们可以参考questionForm

 this.questionForm = this.fb.group({
   question: ['', [this.checkString.bind(this)]],
   other: ['']
 });

然后功能:

checkString(control: FormControl) {
  if(control.value == 'test') {
    this.questionForm.get('other').disable()
  }
  // we need to check that questionForm is not undefined (it will be on first check when component is initialized)
  else if (this.questionForm) { 
    this.questionForm.get('other').enable()
  }
}

这似乎符合它的目的。

Demo

希望这有帮助! :)

答案 1 :(得分:1)

使用反应形式,你可以这样做:

java.lang.NullPointerException: Attempt to invoke virtual method android.content.res.Resources android.content.Context.getResources()' on a null object reference
at android.content.ContextWrapper.getResources(ContextWrapper.java:86)
at android.view.ContextThemeWrapper.getResourcesInternal(ContextThemeWrapper.java:127)                                                                                at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:121)                                                                               atandroid.support.v7.app.AppCompatActivity.getResources(AppCompatActivity.java:549)
at android.content.Context.getString(Context.java:476)
at com.gamingtechnology.parrots.Ads.Adss(Ads.java:69)
at com.gamingtechnology.parrots.Core.ControlCenter1$2.handleMessage(ControlCenter1.java:1188)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

enter image description here

答案 2 :(得分:0)

我首先将一个属性isDisabled添加到您的组件,然后我将使用[disabled]指令。这将解决您的循环问题。

@Component({
    selector: 'my-app',
    template: `
<form [formGroup]="questionForm">

    <input type="text" formControlName="question" />

    <input type="text" formControlName="other" [disabled]="isDisabled" />
</form>
`,
})
export class App {

    isDisabled = false;

    constructor(private fb: FormBuilder) {
        this.questionForm = this.fb.group({
            question: [''],
            other: ['']
        });
    }

    ngOnInit() {
        this.questionForm.valueChanges.subscribe(v => {
            if (v.question === 'test') {
                this.isDisabled = true;
            } else {
                this.isDisabled = false;
            }
        })
    }

}

答案 3 :(得分:0)

使用两个控件和一个* ngIf指令添加另一个解决反应形式问题的答案。见https://github.com/angular/angular/issues/11324

此解决方案可能并不理想,因为它要求您添加第二个表单控件,该控件将在满足更改isDisabled属性的条件时显示。这意味着在提交表单时需要管理两个控件。

@Component({
    selector: 'my-app',
    template: `
<form [formGroup]="questionForm">

    <input type="text" formControlName="question" />

    <input *ngIf="isDisabled" type="text" formControlName="other" disabled />
    <input *ngIf="!isDisabled" type="text" formControlName="other2"  />
</form>
    `
    providers: [FormBuilder]
})
export class App {

    isDisabled = true;

    constructor(private fb: FormBuilder) {
        this.questionForm = this.fb.group({
            question: [''],
            other: [''],
            other2: ['']
        });
    }

    ngOnInit() {
        this.questionForm.valueChanges.subscribe(v => {
            if(v.question === 'test') { 
                this.isDisabled = false;
            } else {
                this.isDisabled = true;
            }
        });
    }

}

如果您愿意,请检查或玩弄羽毛球:

https://plnkr.co/edit/0NMDBCifFjI2SDX9rwcA