最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular 4 - Reactive Forms enabledisable not working - Stack Overflow

programmeradmin9浏览0评论

I am having trouble enabling and disabling a form controls in my application. It is probably because the form is being enabled/disabled in an asynchronous context.

Here is how the code is.

userponent.html

<form [formGroup]="form">
    <input type="text" id="name" formControlName="name" />
    <input type="text" id="age" formControlName="age" />
</form>

userponent.ts

ngOnInit() {

     this._route.queryParams.subscribe(params => {
            getUser(params.userId).subscribe(user => {
                 this._buildForm(user);
            })
     });
}

private _buildForm(user){
    this.form = _fb.group({
        name: [{value: user.name, disabled: user.someCondition}, Validators.required],
        age: [{value: user.age, disabled: user.anotherCondition}, Validators.required]
    })
}    

When the first time the user is loaded upon param change, the controls do get enabled/disabled on the basis of their relevant conditions. When the params change subsequently, the state of the controls remain the same although the values are set appropriately.

I have tried different ways to fix this but no help. For example, I have tried the following at the end of the _buildForm method.

this.form.disable() //Doesn't do anything

this.form.controls.name.disable(); //Doesn't help

One thing that does work as expected is the following (but this isn't what is required).

<button (click)="form.disable()" value="Disable Form" />
<button (click)="form.enable()" value="Enable Form" />

What I feel is that the problem is due the fact the _buildForm() is being called from the asynchronous context (subscribe method).

How can I fix this problem?

UPDATE

Please note that the Observable subscription is triggered on the basis of the navigation as below.

this._router.navigate([], {
   relativeTo: this._route,
   queryParams: {userId: 10}
})

UPDATE 2

This is an easier way to understand my problem

I am having trouble enabling and disabling a form controls in my application. It is probably because the form is being enabled/disabled in an asynchronous context.

Here is how the code is.

user.ponent.html

<form [formGroup]="form">
    <input type="text" id="name" formControlName="name" />
    <input type="text" id="age" formControlName="age" />
</form>

user.ponent.ts

ngOnInit() {

     this._route.queryParams.subscribe(params => {
            getUser(params.userId).subscribe(user => {
                 this._buildForm(user);
            })
     });
}

private _buildForm(user){
    this.form = _fb.group({
        name: [{value: user.name, disabled: user.someCondition}, Validators.required],
        age: [{value: user.age, disabled: user.anotherCondition}, Validators.required]
    })
}    

When the first time the user is loaded upon param change, the controls do get enabled/disabled on the basis of their relevant conditions. When the params change subsequently, the state of the controls remain the same although the values are set appropriately.

I have tried different ways to fix this but no help. For example, I have tried the following at the end of the _buildForm method.

this.form.disable() //Doesn't do anything

this.form.controls.name.disable(); //Doesn't help

One thing that does work as expected is the following (but this isn't what is required).

<button (click)="form.disable()" value="Disable Form" />
<button (click)="form.enable()" value="Enable Form" />

What I feel is that the problem is due the fact the _buildForm() is being called from the asynchronous context (subscribe method).

How can I fix this problem?

UPDATE

Please note that the Observable subscription is triggered on the basis of the navigation as below.

this._router.navigate([], {
   relativeTo: this._route,
   queryParams: {userId: 10}
})

UPDATE 2 https://angular-cvf1fp.stackblitz.io

This is an easier way to understand my problem

Share Improve this question edited Apr 26, 2018 at 19:38 Muhammad Kashif Nazar asked Apr 26, 2018 at 18:25 Muhammad Kashif NazarMuhammad Kashif Nazar 23.9k5 gold badges34 silver badges46 bronze badges 11
  • Not is clear to me. You're trying to disable the submit until all the inputs are pleted? – Jonathan Brizio Commented Apr 26, 2018 at 18:35
  • What is your angular version? – Reza Commented Apr 26, 2018 at 18:41
  • Can you make a plunker or ... for it – Reza Commented Apr 26, 2018 at 18:41
  • This is Angular 4. I can try to make a plunker for it. – Muhammad Kashif Nazar Commented Apr 26, 2018 at 18:58
  • In your headline you've written Angular 2, haven't you @KashifNazar? – Michael W. Czechowski Commented Apr 26, 2018 at 18:59
 |  Show 6 more ments

4 Answers 4

Reset to default 5

You just need enable/disable methods of form control.

Here is stackblitz example. It works perfectly.

@Component({
  selector: 'my-app',
  templateUrl: './app.ponent.html',
  styleUrls: [ './app.ponent.css' ]
})
export class AppComponent  {
  group;
  isDisabled = true;

  constructor(fb: FormBuilder) {
    this.group = fb.group({
      stuff: fb.control({value: 'stuff', disabled: this.isDisabled})
    });
  }

  toggle() {
    this.isDisabled = !this.isDisabled;

    this.group.controls.stuff[this.isDisabled ? 'enable' : 'disable']();
  }
}

You're right. The subscription is only fired once, so after submitting the form the user entity does not change anymore. To do it, add for instance an event handler to your form submit.

user.ponent.html

<form [formGroup]="form" (submit)="_updateForm()">
    <input type="text" id="name" fromControlName="name" />
    <input type="text" id="age" fromControlName="age" />
</form>

user.ponent.ts

private userId: any;


ngOnInit() {
    this._route.queryParams.subscribe(params => {
        this.userId = params.userId;
        this._updateForm();
    });
}

private _buildForm(user){
    this.form = _fb.group({
        name: [{value: user.name, disabled: user.someCondition}, Validators.required],
        age: [{value: user.age, disabled: user.anotherCondition}, Validators.required]
    });
} 

// The update function has to be public to be called inside your template
public _updateForm(){
    getUser(this.userId).subscribe(user => {
        this._buildForm(user);
    });
}    
  • Create the formGroup directly in ngOnit w/controls disabled by default so you're sure it exists w/o worrying about async issues.
  • In this._route.queryParams.subscribe(...) you can use this.form.setValue({//set all control values}) or this.form.patchValue({//set individual controls}) to update the individual controls as needed/once available.
  • Use ponent instance variables for condition and someOtherCondition (or a user object as a whole if you want to separate your data model from the form's model - they don't have to be the same). Initialize these to "false", and refer to them instead for enabling/disabling the controls in the formGroup creation. You can also update those variables in the same .subscribe() block once the user data is in place, instead of waiting to access user data model directly.

This way your controls and formGroup exist, and are disabled, until the async data is available.

<form [formGroup]="form">
    <input type="text" id="name" fromControlName="name" />
    <input type="text" id="age" fromControlName="age" />
</form>

do you see a typo here?fromControlName should be formControlName After that change toggling will work ;)

https://angular-rivxs5.stackblitz.io

发布评论

评论列表(0)

  1. 暂无评论