由于特定于此应用程序的原因,使用数据数组或null
来显示表单列表。区别基于数据是由服务提供还是手动添加的,其中null
表示所有内容都是通过服务手动添加的
按钮而不是服务。
因此,忽略了null
s数组的使用情况,事实证明,基于输入,[null, null, null].splice(0, 1);
删除了索引2的null
而不是0根据数组长度将值转换成不同的显示形式,然后查看删除时谁消失了。
可以通过向数组中添加{ index: theIndex }
之类的独特内容而不是null
来使其工作。因此,拼接现在可以正确地删除索引0而不是2处的项目,但是现在我很好奇拼接在幕后所做的事情,它不能删除索引,而无论其值是多少索引。
有人可以解释splice
在做什么吗?基于spec for splice,我真的不明白为什么会这样。
答案 0 :(得分:1)
(这是从问题中的评论之后得出的,但太大了,无法评论)。
所以我认为您在概念上存在误解(^^)。看这个例子:
let a = [1, 2, 3]
a.splice(0, 1) // => 1
a // => [2, 3]
let b = [1, 2, 3]
delete b[0] // => true
b // => [<1 empty slot>, 2, 3]
splice
函数可就地修改数组 。请注意,尽管我们剪接了第一个元素,但结果却得到了两个元素的数组。
现在看这个例子
let a = [1, 1, 1]
a.splice(0, 1)
a // => [1, 1]
let b = [1, 1, 1]
b.splice(2, 1)
b // => [1, 1]
我们正在从a
中删除第一个元素,而从b
中删除最后一个元素,但是当然没有办法告诉我们,只是看一下结果即可。
在null
的情况下,同样的事情也在发生。一些库(Angular)试图找出您删除了哪个元素,但没有办法知道。这是因为null === null
。
现在,例如,如果您使用空对象的数组,那么将有一种知道的方式。由于{} !== {}
---因为每次转换{}
时都在创建唯一对象 ---,所以您可以知道空数组中缺少哪个元素对象。数组[1, 2, 3]
的情况与此类似。
let a = [{}, {}, {}] // lets imagine that each object has a unique id
// and we have [{}#1, {}#2, {}#3]
let [obj1, obj2, obj3] = a
obj1 === obj2 // => false, because they have different ids.
a.splice(0, 1)
a // => [{}#2, {}#3]
a.includes(obj1) // => false, because {}#1 is no longer in a
因此,使用null
数组的替代方法是使用空对象数组。我认为这就是当您使用{ index: theIndex }
之类的对象时代码为您工作的原因。但是,当然,这一切都取决于Angular的智能程度。我敢打赌,还有一种更自然的删除元素的方法,就像@KaiserKatze指出的那样:“如果映射到您的模型,则直接删除或添加数组中的元素总是一个坏主意。”
您必须了解,在拼接数组时,您只是在做-从数组中删除元素。 在拼接数组时您不会删除“表单元素” 。取而代之的是,一些外来代码正在读取数组,并试图在幕后弄清楚您打算做什么。