Angular NgForOf指令中ngForTrackBy的目的是什么

Angular NgForOf指令中ngForTrackBy的目的是什么,angular,angular-directive,ngfor,Angular,Angular Directive,Ngfor,从角度来看,下面的片段让我感到困惑 /** * A function that defines how to track changes for items in the iterable. * * When items are added, moved, or removed in the iterable, * the directive must re-render the appropriate DOM nodes. * To minimize churn

从角度来看,下面的片段让我感到困惑

 /**
   * A function that defines how to track changes for items in the iterable.
   *
   * When items are added, moved, or removed in the iterable,
   * the directive must re-render the appropriate DOM nodes.
   * To minimize churn in the DOM, only nodes that have changed
   * are re-rendered.
   *
   * By default, the change detector assumes that
   * the object instance identifies the node in the iterable.
   * When this function is supplied, the directive uses
   * the result of calling this function to identify the item node,
   * rather than the identity of the object itself.
   *
   * The function receives two inputs,
   * the iteration index and the node object ID.
   */
  @Input()
  set ngForTrackBy(fn: TrackByFunction<T>) {
    ...
      }
    }
    this._trackByFn = fn;
  }
源代码解释了这一点

提供此函数时,指令使用调用此函数的结果来标识项节点,而不是对象本身的标识

但在上面的示例中,我们无论如何都要传递对象本身的标识(
return hero.id;
),但要通过一个附加函数。我们为什么需要这个?如果我们没有传递任何这样的函数,Angular会不会像文档中默认的那样,获取对象本身的标识

跟踪器函数的显式传递与通常没有跟踪器函数的Angular传递有什么不同


谢谢。

我完全明白这句话的措词可能会令人困惑。但是当它说“而不是对象本身的身份”时,我可以清楚地看到它的措辞是多么令人困惑。但是当它说“而不是对象本身的标识”时,Angular将检查内存中的引用是否为非基本类型。如果不传入
trackById
方法,则每次数组更改时,它都会认为每个对象都是新的,并重新创建所有DOM节点

如果传递它
trackById
,它将用新对象检查原始对象,如果它们的
id
属性相同,则表示它们是相同的对象,并且不会重新绘制该DOM节点

下面是一个您也可以运行的示例,它是纯javascript

let obj1={id:1,名称:'test'};
设obj1a={id:1,name:'test'};
设prim1=1;
设prim2=1;
常量checkById=(a,b)=>{
返回a.id==b.id;
}
//obj1和1a不一样,因为它们在内存中是不同的引用
console.log(“obj1==obj1a”,obj1==obj1a);
//不过,ob1和obj1a对我们来说是“相同的”,因为ID属性是相同的
log(“checkById(obj1,obj1a)”,checkById(obj1,obj1a));
//原语是平等的

log(“prim1==prim2”,prim1==prim2)Angular将检查内存中的引用是否为非基本类型。如果不传入
trackById
方法,则每次数组更改时,它都会认为每个对象都是新的,并重新创建所有DOM节点

如果传递它
trackById
,它将用新对象检查原始对象,如果它们的
id
属性相同,则表示它们是相同的对象,并且不会重新绘制该DOM节点

下面是一个您也可以运行的示例,它是纯javascript

let obj1={id:1,名称:'test'};
设obj1a={id:1,name:'test'};
设prim1=1;
设prim2=1;
常量checkById=(a,b)=>{
返回a.id==b.id;
}
//obj1和1a不一样,因为它们在内存中是不同的引用
console.log(“obj1==obj1a”,obj1==obj1a);
//不过,ob1和obj1a对我们来说是“相同的”,因为ID属性是相同的
log(“checkById(obj1,obj1a)”,checkById(obj1,obj1a));
//原语是平等的

log(“prim1==prim2”,prim1==prim2)
如果我没有弄错的话,这与Vue语法类似
  • {{{item.message}
  • ,除了在Angular的情况下,我必须定义一个跟踪函数,返回跟踪DOM节点的索引。我不熟悉Vue,但我猜它有一个内置的方法,通过提供一个键来做同样的事情,这样它就可以比较这两个值。Angular让您提供一个自定义函数来运行,虽然我只使用它来通过对象“键”进行比较,但可能还有其他属性或多个属性,或者您还需要检查一些其他逻辑,这样可以提供更大的灵活性。因此,如果我做对了,这类似于
  • {{item.message}
  • 除了Angular之外,我必须定义一个跟踪函数,该函数返回跟踪DOM节点的索引。我不熟悉Vue,但我猜它有一个内置方法,通过提供一个键来执行相同的操作,以便它可以比较这两个值。Angular是否提供了一个自定义函数to运行,虽然我只使用它来比较对象“键”,但可能还有其他属性或多个属性,或者您还需要检查一些其他逻辑,因此这允许更大的灵活性。
    trackById(index: number, hero: Hero): number { return hero.id; }