我正在尝试制作一个在foreach绑定中使用的自定义绑定,并且需要访问当前的observableArray
和$data
。
现在我注意到bindingContext
arg包含$data, $parent, $root
等但是我似乎无法找到一种方法来访问正在迭代的数组,所以有办法吗?
这里要清楚的是我的意思的一个例子:
<div data-bind="foreach: People">
<button data-bind="customBinding: someArg">DoSomethingWithArrayAndElement</button>
</div>
在这种情况下,customBinding
似乎会产生:
People
数组答案 0 :(得分:2)
我不确定这是否可行,但如果没有进一步了解您的应用程序,我唯一可以建议的是:制作一个自定义foreach
绑定,以暴露整个数组。
ko.bindingHandlers.customForeach = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var newBindingContext = bindingContext.extend({iterator: valueAccessor()});
return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, newBindingContext);
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var newBindingContext = bindingContext.extend({iterator: valueAccessor()});
return ko.bindingHandlers.foreach.update(element, valueAccessor, allBindingsAccessor, viewModel, newBindingContext);
}
};
var ViewModel = function ViewModel() {
this.items = ko.observableArray(['a', 'b', 'c', 'd']);
};
ko.applyBindings( new ViewModel() );
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="customForeach: items">
<li data-bind="text: $data"></li>
</ul>
这会为您的bindingContext添加一个新的iterator
属性,从而在其中公开完整的数组。
答案 1 :(得分:2)
那么您的目标是在foreach
模板中访问基础数组?如果您问我,那么不应该以这种方式为您的代码建模。
话虽如此,您真正需要的只是数组的别名,并确保在使用foreach
绑定时设置别名。当然,有很多方法可以做到这一点。
最简洁的方法可能是创建一个alias
绑定处理程序。然后扩展现有的foreach
绑定以添加别名或创建一个新别名。
ko.bindingHandlers.alias = {
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var value = valueAccessor();
var aliasValue = value.data;
aliasName = value.aliasName || '$alias';
if (ko.isObservable(aliasValue)) {
var rawValue = aliasValue,
rawAliasName = value.rawAliasName || '$rawAlias';
bindingContext[rawAliasName] = rawValue;
aliasValue = rawValue();
}
bindingContext[aliasName] = aliasValue;
}
};
ko.bindingHandlers.foreachex = {
preprocess: function (value, name, addBinding) {
addBinding('alias', "{ data: "+value+", aliasName: '$source', rawAliasName: '$rawSource' }");
addBinding('foreach', value);
}
};
然后您可以在视图中使用别名。
<div data-bind="foreachex: People">
<!-- $rawSource is the People observable array -->
<button data-bind="customBinding: someFunction($rawSource, $data)">
DoSomethingWithArrayAndElement
</button>
</div>