Angular 2:如何在ngOnInit / ngOnChanges

时间:2017-02-07 22:27:40

标签: angular typescript

问题

我正在创建一个具有2个@Input()属性的组件,它们碰巧彼此依赖。这是一个例子(你也可以看到this plunk):

@Component({
  selector: 'my-select',
  template: `
    <ul>
      <li *ngFor="let item of items">
        {{ item }}
        <span *ngIf="item === default">(default)</span>
        <button *ngIf="item !== default" (click)="makeDefault(item)">Make default</button>
      </li>
    </ul>
  `,
}) export class MyInput implements OnInit {
  @Input() public items: string[] = [];

  @Input() public defaultValue: string;
  @Output() public defaultValueChange = new EventEmitter<string>();

  public makeDefault(item: string): void {
    this.defaultValue = item;
    this.defaultValueChange.emit(this.defaultValue);
  }

  public ngOnInit(): void {
    if (!this.defaultValue) {
      // choose the first item, since there always must be a default
      this.makeDefault(this.items[0]);
    }
  }
}

实际问题是我在正在进行的更改检测周期中更改了@Input()属性值,这不是很棒(导致Angular抛出错误)。假设

,就会发生这种情况
<my-select [(default)]="defaultItem" ...></my-select>
使用

语法,这正是预期的使用模式。

我可以通过使用makeDefault进行setTimeout调用来解决此问题,如下所示:

  public ngOnInit(): void {
    if (!this.defaultValue) {
      setTimeout(() => {
        this.makeDefault(this.items[0]);
      }, 0);
    }
  }

但这很难看,恕我直言。

处理此类互动模式的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

要设置默认值,您必须使用:

[defaultValue]="default"

[(defaultValue)]="default"

查看更新后的plnkr。我也连接了defaultValueChange事件。

评论更新:

此外,而不是初始化&#39;默认&#39;在my-app模板中,使用App类中声明的默认值也克服了这个问题:

<my-select [(default)]="defaultItem" ...></my-select>

export class App {
  defaultItem = 'default';
  items = ['item 1', 'item 2', 'item 3'];
  constructor() {
    this.name = 'Angular2'
  }
}