简体   繁体   中英

Child's @Input() value does not change in angular 2

I need to change the data in my Child's @Input value on click event from a parent. This is how I do it in:

Parent

update(user: SampleData): void {
        this.sampleToUpdate = user;
      }

<td style="text-align: center;">
                     <button class="btn btn-icon btn-outline-info btn-sm" (click)="update(item)">
                      <i class="nc-icon nc-badge"></i>
                     </button>
                   </td>
<app-sample *ngIf="sampleToUpdate" [sampleData]="sampleToUpdate"></app-sample>

Child

 @Input() sampleData: SampleData;
ngOnInit(): void {
    if (this.sampleData) {
      debugger;
      this.isUpdating = true;
      this.nameToUpdate = `Updating ${this.sampleData.firstName} ${this.sampleData.lastName}`
    } else {
      this.isUpdating = false;
      this.nameToUpdate = `Add New Sample`
    }
    this.createForm();
  }

  createForm(): void {
    if (!this.sampleData) {
      this.firstNameControl = new FormControl(this.sampleData.firstName, {
        validators: [Validators.required],
        updateOn: 'blur'
      });
      this.middleNameControl = new FormControl(this.sampleData.middleName);
      this.lastNameControl = new FormControl(this.sampleData.lastName, {
        validators: [Validators.required],
        updateOn: 'blur'
      });
      this. loadAmountControl = new FormControl(this.sampleData.loadAmount, {
        validators: [Validators.required, DecimalValidators.isNumberCheck],
        updateOn: 'blur'
      })
    } else {
      this.firstNameControl = new FormControl('', {
        validators: [Validators.required],
        updateOn: 'blur'
      });
      this.middleNameControl = new FormControl('');
      this.lastNameControl = new FormControl('', {
        validators: [Validators.required],
        updateOn: 'blur'
      });
      this. loadAmountControl = new FormControl(0.00, {
        validators: [Validators.required, DecimalValidators.isNumberCheck],
        updateOn: 'blur'
      })
    }

    this.form = new FormGroup({
      firstName: this.firstNameControl,
      middleName: this.middleNameControl,
      lastName: this.lastNameControl,
      loadAmount: this.loadAmountControl
    });
 }

On the first instance of the click, I get the result I wanted but on the succeeding clicks, the value does not change anymore. Can you show me how to do this right please? Thank you.

It is because you call createForm() on ngOnInit which is called only once when the component is inited.

You use *ngIf="sampleToUpdate" to conditionally render the child component. But if the value is changed without getting a falsy value, the child component will not be re-rendered and ngOnInit will not be called.

You can use setter at sampleData attribute to perform the logic as followings:

private _sampleData: SampleData;

@Input() 
set sampleData(value:SampleData) {
    this._sampleData = value;
    if (this._sampleData) {
      debugger;
      this.isUpdating = true;
      this.nameToUpdate = `Updating ${this._sampleData.firstName} ${this._sampleData.lastName}`
    } else {
      this.isUpdating = false;
      this.nameToUpdate = `Add New Sample`
    }
    this.createForm();
  }

OR

You can use ngOnChanges lifecycle hook to get the sampleData changes as followings:

ngOnChanges(changes: SimpleChanges): void {
    // changes.sampleData will have previous and current value
    if (changes.sampleData.currentValue) {
      debugger;
      this.isUpdating = true;
      this.nameToUpdate = `Updating ${this.sampleData.firstName} ${this.sampleData.lastName}`
    } else {
      this.isUpdating = false;
      this.nameToUpdate = `Add New Sample`
    }
    this.createForm();
  }

To detect changes in the input you can use ngOnChanges

ngOnChanges(changes: SimpleChanges) {
 if(changes.sampleData) {
 // Add your logic
 }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM