gpt4 book ai didi

javascript - 增强 Knockout 中的数组项上下文

转载 作者:行者123 更新时间:2023-11-28 01:48:41 28 4
gpt4 key购买 nike

目前,当使用 Knockout foreach 绑定(bind)时,您可以使用 $index 访问当前索引。我想让其他类似的功能可用于我的内部绑定(bind) - 例如:

  • array(让我访问正在操作的数组)
  • length(所述数组的长度)
  • first(当前项是否为第一项)
  • last(当前项是否是最后一项)
  • only(当前项目是否是唯一项目)

你明白了。不幸的是,设置 $index 的代码深埋在 template 绑定(bind)的代码中,没有明显的方法来增强上下文。

我可以通过扩展 bindingContext 的自定义 foreach 绑定(bind)来访问 arraylength (我知道这个 re: destroy 有一些警告,但它对我有用),但我无法弄清楚如何实现需要在没有自定义的情况下访问“当前”项目的其他方法为每个数组迭代执行的内部绑定(bind)。

我希望能够做这样的事情:

<div data-bind="foreach: items">
<input type="text" data-bind="value: description" />
<button data-bind="visible: $last, click: $array.push({})">Add Another</button>
</div>

(众所周知,$array$last 都不存在)。假设 button 元素可能来自外部模板,无法知道如何路径到当前数组(因此 $parent.items.push 将不起作用对我来说)。

有办法做到这一点吗?

最佳答案

我能想到的最好办法是创建专门的绑定(bind)来存储有关数组和当前项目的上下文信息。

自定义 foreach 绑定(bind),公开有关数组的上下文:

ko.bindingHandlers.xforeach = (function() {
var createContext = function(array) {
return {
'$array': array,
'$arrayLength': function() { return ko.unwrap(array).length; }
};
};
return {
init: ko.bindingHandlers.foreach.init,
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var extendedContext = createContext(valueAccessor());
return ko.bindingHandlers.foreach.update.call(this, element, valueAccessor, allBindings, viewModel, bindingContext.extend({
'$foreachContext' : extendedContext
}));
}
};
})();
ko.virtualElements.allowedBindings.xforeach = true;

自定义模板绑定(bind),公开有关项目/数组的上下文:

ko.bindingHandlers.xforeachItem = (function() {
var createContext = function(currentContext, forEachContext) {
return {
first: function() { return currentContext.$index() === 0; },
last: function() { return currentContext.$index() === (forEachContext.$arrayLength() - 1); }
};
};
return {
init: ko.bindingHandlers.template.init,
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var extendedContext = createContext(bindingContext, bindingContext.$parentContext.$foreachContext);
return ko.bindingHandlers.template.update.call(this, element, valueAccessor, allBindings, viewModel, bindingContext.extend({
'$foreachItemContext' : extendedContext
}));
}
};
})();
ko.virtualElements.allowedBindings.xforeachItem = true;

使用示例:

<div data-bind="xforeach: items">
<div data-bind="xforeachItem: {}">
<input type="text" data-bind="value: description" />
<span data-bind="visible: $foreachItemContext.first(), text: $foreachContext.$arrayLength()"></span>
<button data-bind="visible: $foreachItemContext.last(), click: $root.add">Add Another</button>
</div>
</div>

最后,一个 fiddle 展示了它的实际效果:http://jsfiddle.net/magnafides/wkCLd/2/

关于javascript - 增强 Knockout 中的数组项上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19983885/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com