Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 防止元素的再创造_Javascript_Html_Arrays_Angular_Observable - Fatal编程技术网

Javascript 防止元素的再创造

Javascript 防止元素的再创造,javascript,html,arrays,angular,observable,Javascript,Html,Arrays,Angular,Observable,所以我有一个组件,它用动画加载div。 div是基于数据源显示的 *注意:在这个示例中,我使用了大量的,这是因为我还没有确定模型 apiService.ts dataArray:可观察; 构造函数(){ 这是getUpdateData(); setInterval(()=>this.getUpdateData(),1000); } getUpdateData(){ this.httpClientCall() .订阅((响应:任意)=>{ this.dataArray=响应; }); } com

所以我有一个组件,它用动画加载div。 div是基于数据源显示的

*注意:在这个示例中,我使用了大量的
,这是因为我还没有确定模型

apiService.ts

dataArray:可观察;
构造函数(){
这是getUpdateData();
setInterval(()=>this.getUpdateData(),1000);
}
getUpdateData(){
this.httpClientCall()
.订阅((响应:任意)=>{
this.dataArray=响应;
});
}
component.html


{{data.some_value_,可以更新}
简单分解:我每分钟从远程位置提取数据,并让响应成为
dataArray
中的新数据

我遇到的问题是,在每次更新时,整个
panels
div的内容都会被替换。 我只希望更新值,而不是重新渲染整个div

数组本身由对象组成,我真正喜欢做的是更新数组中的对象属性,而不是替换整个对象数组。更精确;比较两个数组并检查对象的属性是否存在差异

例如:

[
0:{id:1,名称:a,组:'a'},
1:{id:2,名称:b,组:'b'},
2:{id:3,名称:c,组:'c'},
]
新数据(来自httpClient):

[
0:{id:1,名称:a,组:'b'},
1:{id:2,名称:b,组:'b'},
2:{id:3,名称:c,组:'c'},
]
在本例中,我想更新数组中的第一个对象,因为组字符串已更改,而没有替换整个对象数组

我永远感谢您提供了一个为什么/如何解决这个问题的解决方案,而不仅仅是解决这个问题的代码。
提前谢谢你

*ngFor
可以利用函数将数组元素与DOM元素关联起来。这允许angular更有效地更新DOM,因为它不再销毁和重新创建所有项,而只创建新项

只需在控制器中创建一个小功能:

trackById=(索引:编号,项目:项目)=>item.id;
然后将其添加到您的
*ngFor
,如下所示:

<div class="panels" *ngFor="let data of apiService.dataArray; trackBy: trackById">
    <div class="panel-that-has-animation">
        {{ data.some_value_that_can_be_updated }}
    </div>
</div>
致:

dataArray$:Observable=计时器(0,1000).pipe(
switchMapTo(this.httpClientCall())
);

这样做的另一个好处是懒惰;i、 e.-如果没有订阅
dataArray$
,您将不会轮询服务器。

this.dataArray=[…新设置([…(this.dataArray | |[…),…response])]
这可能会解决您的问题。
ngFor
结构化指令的
trackBy
功能可能就是您要查找的@AdarshMohan这给出了多个错误:
Type'any[]”缺少类型“Observable”中的以下属性:
Type'Observable | undefined[]”必须有一个返回迭代器的“[Symbol.iterator]”方法。
您能否解释一下这是怎么回事?如果我了解它的作用,我可能能够调整它,使其符合我的目的。它所做的是创建当前和以前阵列的平面阵列,然后创建一个唯一的集
trackBy:
绝对是我需要的!谢谢你的详细解释!
constructor(){
   this.getUpdateData();
   setInterval(()=> this.getUpdateData(), 1000);
}

getUpdateData(){
    this.httpClientCall()
    .subscribe((response: any) => {
      this.dataArray = response;
    });
  }
dataArray$: Observable<Array<any>> = timer(0, 1000).pipe(
    switchMapTo(this.httpClientCall())
);