繁体   English   中英

当数组元素相同时,为什么 Splice 只删除最后一个元素

[英]Why Splice removes only last element when array elements are the same

转到此StackBlitz 链接Not Working

转到此StackBlitz 链接Working Fine

我的问题是关于Array.splice 当数组数据不同时,Array.splice 工作正常,但当数组数据类型相同时, Array.splice只删除最后一个索引。 在这种情况下, splice 忽略提供的索引以从数组中删除元素。

两个示例都有通用的 HTML 模板

<div class="container">
    <table class="table table-dark table-striped table-hover">
        <thead>
           <tr>
               <td scope="col"> Index </td>
               <td scope="col"> Value </td>
               <td scope="col"> Action </td>
           </tr>
        </thead>
        <tbody>
            <tr *ngFor="let row of rows; let i = index"  [@itemAnim]>
                <td> {{i}} </td>
                <td>{{row}}</td>
                <td><button class="btn btn-danger" (click)="deleteRow(i)">Delete</button></td>
           </tr>
        </tbody>
    </table>
    <button class="btn btn-primary " (click)="addRow()">Add row</button>
</div>

请参阅此示例按预期工作

index = 1;
rows = [1]; 

addRow() {   
   this.rows.length > 0 ?  this.index ++ : this.index = 1;
   this.rows.push(this.index)
}

deleteRow(row: number) {
   return this.rows.length > 0 ? this.rows.splice(row, 1) : this.index = 1;
}

这不起作用

rows = [1]; 

addRow() {   
  this.rows.push(1)
}

deleteRow(row: number) {
   this.rows.splice(row, 1) ;
}

在上面的代码中,当单击addButton时,我只推送1 而删除按钮只从最后一个索引中删除,而不是提供行号索引。

我的问题是为什么会这样? 上面的 stackBlitz 链接显示了相同的歧义。

因为您实际上是在删除选定的索引,但是 Angular 没有任何关于值之间差异的信息,我们来看一个示例:

我们有这个数组: [1, 1, 1, 1]并且您删除第二项,然后删除之前的 angular 将看到:

[1, 1, 1, 1]

之后:

[1, 1, 1]

此时 angular 只知道少了一项,但不知道希望项,然后 angular 只删除最后一项。

您需要确保传递不同的值或引用(推荐),然后 angular 将知道如何区分数组项。

您可以使用以下对象修复它: { data: 1 } ,您的数组将如下所示:

[
  { data: 1 },
  { data: 1 },
  { data: 1 },
  { data: 1 }
]

为什么这会起作用? 因为引用不相同(值与引用类型),即使数据相同,angular 也会看到不同的引用。

这对你有用:

rows = [{ data: 1 }]; 

addRow() {   
  this.rows.push({ data: 1 });
}

deleteRow(row: number) {
  this.rows.splice(row, 1);
}

在这个例子中,你总是传递一个带有自己引用的新对象。


这另一个例子将不起作用

sameReference = { data: 1 };

rows = [this.sameReference]; 

addRow() {   
  this.rows.push(this.sameReference);
}

deleteRow(row: number) {
  this.rows.splice(row, 1);
}

因为sameReference变量存储的是引用,而不是对象,并且 angular 不会(再次)知道项目之间的差异,另外当你改变一个元素的数据值时,所有元素都会得到那个值,因为只有一个对象被引用 N数组内的次数。


这也行

sameReference = { data: 1 };

rows = [{ ...this.sameReference }]; 

addRow() {   
  this.rows.push({ ...this.sameReference });
}

deleteRow(row: number) {
  this.rows.splice(row, 1);
}

因为这里我们将对象的值复制到具有不同引用的新对象中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM