angular2 如何决定是更新还是重新创建一个组件?

How does angular2 decide whether to update or recreate a component?

假设我有一个 Angular2 组件,它有一些输入属性,比如

@Component(...)
class ChildComponent {
   @Input() input1: string;
   @Input() input2: number;
   internalState: any;
}

在另一个组件中使用,甚至可能在列表中使用,例如:

<li *ngFor="#item of items">
  <child-component [input1]="item.a" [input2]="item.b">
  </child-component>
</li>

输入参数发生变异的地方:

Angular2 如何决定是否应更新子组件(将输入变量设置为新值并调用 ngOnChanges 生命周期挂钩)或是否应销毁子组件并创建新组件?是否有可能影响行为?

我问的原因是因为如果组件除了输入参数之外还有任何内部状态,那么更新或重新创建它会有所不同。在更新的情况下,它将保留旧的内部状态(例如,如果某些东西被折叠,如果用户输入了某些东西),在重新创建的情况下,我们将获得一个具有默认状态的新初始化组件。

根据组件的不同,我肯定有时需要第一种方法,有时需要另一种方法。

如果组件有一些复杂的初始化逻辑并且不存储用户数据,那么我认为将输入视为不可变并且只在 ngOnInit 中初始化组件一次而不是考虑需要在 ngOnChanges.

当存在像给定示例中那样的子组件列表时,问题变得更加棘手。如果为我提供列表的服务现在在列表中间插入一个新项目并给我一个更新的列表(可以是不可变列表的变异或新版本) - angular2 怎么知道我想要一个新的要在列表中间创建项目而不是用新值更新现有项目并在末尾创建新项目?后一种方法会将先前现有项目的内部状态转移到新项目,并且先前现有项目的输入数据将分配给新创建的组件。

引自NgFor docs

Angular uses object identity to track insertions and deletions within the iterator and reproduce those changes in the DOM. This has important implications for animations and any stateful controls (such as <input> elements which accept user input) that are present. Inserted rows can be animated in, deleted rows can be animated out, and unchanged rows retain any unsaved state such as user input.

您可能需要阅读文档中的一些其他详细信息。