Angular 無法觸發子組件@Input()值變化的奇怪問題

子組件:TitleComponent

title.component.ts

import { Component, EventEmitter, Input, Output } from '@angular/core';

@Component({
    selector: 'app-title',
    template: `<h2>{{title}}</h2><br/>
    <ul *ngFor="let message of messages"><li>{{message}}</li></ul><br/>
    <button (click)="click()">確定</button>&nbsp;&nbsp;
    <button (click)="update()">值變更</button>
    `
})
export class TitleComponent {
    @Input() title = '';
    @Input() messages: string[] = [];
    @Output() output: EventEmitter<any> = new EventEmitter();
    constructor() { }

    click(): void {
        this.output.emit();
    }

    update(): void {
        this.title = 'hello';
        this.messages = [];
    }
}

父組件:Tab1Page

tab1.page.html

<app-title (output)="output()" [title]="title" [messages]="messages"></app-title>

tab1.page.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-tab1',
  templateUrl: 'tab1.page.html',
  styleUrls: ['tab1.page.scss']
})
export class Tab1Page {
  title:string = '';
  messages:string[] = [];

  constructor() {}

  public output(): void {
    this.title = 'world';
    this.messages.push('how are you');
  }
}

點擊確定按鈕

再次點擊

好了沒問題,現在點擊值變更按鈕

然後再點擊確定按鈕,發現不管點擊多少次都是下面這個樣子

很奇怪吧。現在我們修改下tab1.page.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-tab1',
  templateUrl: 'tab1.page.html',
  styleUrls: ['tab1.page.scss']
})
export class Tab1Page {
  title:string = '';
  messages:string[] = [];
  int: number = 1;

  constructor() {}

  public output(): void {
    this.int++;
    this.title = 'world ' + this.int;
    const messages = [];
    messages.push('how are you');
    this.messages = messages;
  }
}

重新執行上面的操作,值變更後點確定

會一直有值,這是爲什麼呢?我個人猜測是第一次的時候沒有觸發angular的贓檢測,而第二次因爲兩個變量的值改變並且內存地址也改變所以觸發的贓檢測。

遇到這種解決辦法:

一、使用@ViewChild

<app-title #apptitle (output)="output()" [title]="title" [messages]="messages"></app-title>

import { Component, ViewChild } from '@angular/core';
import { TitleComponent } from '../title/title.component';

@Component({
  selector: 'app-tab1',
  templateUrl: 'tab1.page.html',
  styleUrls: ['tab1.page.scss']
})
export class Tab1Page {
  @ViewChild('apptitle') apptitle: TitleComponent;
  title:string = '';
  messages:string[] = [];

  constructor() {}

  public output(): void {
    this.apptitle.title = 'world';
    this.apptitle.messages.push('how are you');
  }
}

二、對於數組有兩種辦法

1)清空值的時候不要用this.messages = [];這種重新賦值的方式,用下面方式清空數組

this.messages.splice(0);

2)在賦值的時候採用es6的寫法

this.messages= [...this.messages, 'how are you'];

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章