为什么* ngFor in angular not print push方法输入的最后一个值

时间:2017-06-06 08:36:02

标签: angular lifecycle

我不知道为什么日志,即字符串数组没有在列表项<li *ngFor="let log of logs"><code>{{ log }}</code></li>中的“Destroy - child”上打印它的值,并且相同的字符串数组在{{Destroy - child“中正确打印1}}。  
这意味着值被插入数组中,这是什么原因不能打印?

PLZ解释,我完全糊涂了。


相同示例的链接:http://plnkr.co/edit/kBHV6AximaHAC26kYEOA?p=gitter
打开此链接并运行它。

app.component.ts

{{ logs.join(', ') }}

child.component.ts

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

@Component({
    selector: 'app-root',
    template: `
      <h5>Lifecycle Events Log</h5>
      {{ logs.join(', ') }}

      <ul>
        <li *ngFor="let log of logs">
          <code>{{ log }}</code>
        </li>
      </ul>


      <app-child 
        *ngIf="showChild" 
        [name]="name"
        (log)="onLog($event)">
      </app-child>
    `
})
export class AppComponent implements OnInit {
  name = 'Alice';
  logs: string[] = [];
  showChild = true;

  ngOnInit() {
    setTimeout(() => this.updateName(), 3000);
    setTimeout(() => this.hideChild(), 4000);
  }

  updateName() {
    this.name = 'Bob';
  }

  hideChild() {
    this.showChild = false;
    this.logs.push(`onDestroy--app`);
  }

  onLog(data) {
    this.logs.push(data);
  }

}

输出: 执行完所有方法后

import {
  Component,
  Input,
  Output,
  SimpleChange,
  OnChanges, 
  OnInit,
  DoCheck,
  AfterContentInit,
  AfterContentChecked,
  AfterViewInit,
  AfterViewChecked,
  OnDestroy,
  EventEmitter
} from '@angular/core';

@Component({
    selector: 'app-child',
    template: `
      <div>
        <h4>Child Component</h4>
        <p>{{ name }}</p>
    </div>
    `,
    styles: [`
      :host > div {
        border: 2px solid blue;
        padding: 0.5rem 1rem;
        margin-top: 4rem;
      }
    `]
})
export class ChildComponent implements OnChanges, OnInit, DoCheck, AfterContentInit,
  AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy {

  @Input() name = '';

  @Output() log = new EventEmitter<string>();

  _verb = 'set';
  _onChangesCounter: number = 0;

  // Only called if there is an [input] variable set by parent.
  ngOnChanges(changes: { [propertyName: string]: SimpleChange }) {
    let changesMsgs: string[] = [];

    for (let propName in changes) {
      if (propName === 'name') {
        let name = changes['name'].currentValue;
        changesMsgs.push(`name ${this._verb} to "${name}"`);
      } else {
        changesMsgs.push(propName + ' ' + this._verb);
      }
    }
    this.log.emit(`onChanges (${this._onChangesCounter++}): ${changesMsgs.join('; ')}`);
    this._verb = 'changed';
  }

  ngOnInit() {
    this.log.emit(`onInit`);
  }

  ngDoCheck() {
    this.log.emit(`doCheck`);
  }

  ngAfterContentInit() {
    this.log.emit(`afterContentInit`);
  }

  // Called after every change detection check
  // of the component (directive) CONTENT
  // Beware! Called frequently!
  ngAfterContentChecked() {
    this.log.emit('afterContentChecked');
  }

  ngAfterViewInit() {
    this.log.emit(`afterViewInit`);
  }

  // Called after every change detection check
  // of the component (directive) VIEW
  // Beware! Called frequently!
  ngAfterViewChecked() {
    this.log.emit(`afterViewChecked`);
  }

  ngOnDestroy() {
    this.log.emit(`onDestroy--child`);
  }
}

1 个答案:

答案 0 :(得分:0)

似乎是一个错误,在子组件的ngDestroy之后,更改检测无法正确执行。如果在日志方法中添加detectChanges,您将获得所需的效果。

plnkr

你应该只在有ngOnDestroy事件时才这样做,因为如果你在ngDoCheck或类似的事情上这样做,你将会陷入无限循环。它不断检查和记录:)

我不知道你的用例,但是如果你真的需要这个功能,你可以在github上发布错误报告