简体   繁体   中英

Angular 8. My view is not updated on model change

In my application I'm having a big trouble 'refreshing' the view after model for that view was updated. Mainly when API call is resolved and its response's data should be published on that view.

This my component management.component.ts ts file (I've removed code not important to this issue):

import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-service',
  templateUrl: './service.component.html',
  styleUrls: ['./service.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class ServiceComponent implements OnInit {
  serviceForm: FormGroup;
  notificationStatus: boolean;

  constructor(
    private http: HttpClient
  ) { }

  ngOnInit() {
    this.buildServiceForm();

    // Example endpoint response: { active: false }
    this.getNotificationInfo().subscribe((data: object) => {
      this.notificationStatus = data['active'];
    })
  }

  submit()
  {
    this.notificationStatus = !this.notificationStatus;
  }

  buildServiceForm()
  {
    this.serviceForm = this.formBuilder.group({
      message_de: ['', { validators: [Validators.required] }],
      message_en: ['', { validators: [Validators.required] }]
    });
  }

  getNotificationInfo() {
    return this.http.get(this.apiPath + 'service/notifications');
  }
}

And this is the part in HTML that is responsible for displaying that model (button tag):

<form [formGroup]="serviceForm" (ngSubmit)="submit()">
    <mat-form-field class="service__form__textarea">
      <textarea matInput formControlName="message_de"></textarea>
    </mat-form-field>
    <mat-form-field class="service__form__textarea">
      <textarea matInput formControlName="message_en"></textarea>
    </mat-form-field>

    <button>
      <span *ngIf="notificationStatus == false"> Service Off </span>
      <span *ngIf="notificationStatus == true"> Service On </span>
    </button>
</form>

Whenever the button is clicked a form is submitted and the button's text should be updated (changed with use of ngIf) right away. But it only happens when I click randomly other objects on website.

I tried already with use of changeDetection: ChangeDetectionStrategy.OnPush but with no luck. Here animation how it looks like in practice - after clicking the button its text changes only after clicking in textarea and not right after clicking the button: gif animation of the behavior

Any one have any idea how can I refresh my view or what is the reason why my view behaves like that?

When using ChangeDetectionStrategy.OnPush the view will only update if object references change (see angular 2 change detection and ChangeDetectionStrategy.OnPush ).

You may need to run the update to notificationStatus inside of zone using zone.run if that service is not already inside zone (the default Http client for example is already run inside zone automatically).

You also need to manually update the view using ChangeDetectorRef , or use the async pipe and observables which do this automatically.

You have two way to solve this:

  1. Use CDR (quick & dirty)

Inject in your costructor ChangeDetectorRef Call "cdr.markForCheck();" at the end of the submit method.

  1. Transform your notificationStatus in a subject In the class:

    private notificationStatus$:Subject = new Subject(true);

In the submit method:

this.notificationStatus$:Subject.next(false);

In the html:

<span *ngIf="(notificationStatus$ | async ) == false"> Service Off </span>

PS: The $ in the variable name is a convention for obserable/subject

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