将两个WinJS.Binding.List连接为一个

Concat two WinJS.Binding.List into one

本文关键字:连接 一个 List WinJS 两个 Binding      更新时间:2023-09-26

我正在尝试将2个WinJS.Binding.List合并为一个。我在MSDN上看到了.concat方法,但它似乎不起作用。有人能告诉我怎么做吗?

输入:

var a = new WinJS.Binding.List([1,2])
var b = new WinJS.Binding.List([3,4])

期望输出:一个WinJS.Binding.List,其中包含数字1,2,3,4。

我尝试了a.concat(b),但它返回一个3元素数组而不是WinJS.Binding.List。这是控制台的日志。

var a = new WinJS.Binding.List([1,2])
var b = new WinJS.Binding.List([3,4])
a.concat(b)
==> [object Array][...]

知道为什么和如何正确地做吗?

注:我知道我可以遍历b中的每个项目并将其推入a,但是否存在更有效的方法?我也不想在将它们转换为WinJS.Binding.List之前连接数组,因为我正在从2个不同的数据源进行2次异步调用。上面的代码只是一个简化的示例。

您可以从列表中获取两个数组(使用slice),将它们连接起来,然后创建一个新列表。

var a = new WinJS.Binding.List([1, 2]);
var b = new WinJS.Binding.List([3, 4]);
var ab = new WinJS.Binding.List(a.slice(0).concat(b.slice(0)));

也可以使用list concat方法(与js的本地concat相反)使其更短:

var a = new WinJS.Binding.List([1, 2]);
var b = new WinJS.Binding.List([3, 4]);
var ab = new WinJS.Binding.List(a.concat(b.slice(0)));

从你的描述中,我假设你的数据是从不同的来源返回的,并且是(a)已经在单独的WinJS.Binding.List实例中,使得投影不可行或(b)语义上不同,足以保证在单独的List实例中存储。

在这种情况下,我的方法可能是使用事件侦听器沿以下行同步已连接列表:
[list1, list2].forEach (list) ->
  list.oniteminserted = (event) -> joinedList.push(event.detail.value)
  list.onitemremoved = (event) -> joinedList.splice(joinedList.indexOf(event.detail.value),1)

(要用addEventListener和相应的removeEventListener替换,以增加复杂性;))此方法的缺点是您几乎无法控制最终列表中项的顺序,这将保证另一个排序谓词,即在该模型中进一步的开销。

最后,很可能在两个列表中都放置一个好的旧.forEach (item) -> joinedList.push(item)是解决这个问题的最直接和最合适的方法。

编辑:为了更深入地了解我使用投影的建议,我想到了这样的东西:
# put all items in the "big" list
item1.source = 'list1'
joinedList.push(item1)
item2.source = 'list2'
joinedList.push(item2)
# create separate lists using projection
list1 = joinedList.createFiltered (i) -> i.source is 'list1'
list2 = joinedList.createFiltered (i) -> i.source is 'list2'