敲除 foreach 中的自定义绑定以获取迭代器
Knockout custom binding in foreach to get iterator
我正在尝试制作要在 foreach 绑定中使用的自定义绑定,并且需要访问当前 observableArray
和 $data
.
现在我注意到 bindingContext
arg 包含 $data, $parent, $root
等,但是我似乎无法找到一种方法来访问正在迭代的数组,那么有什么办法吗?
为了清楚起见,这里有一个例子可以说明我的意思:
<div data-bind="foreach: People">
<button data-bind="customBinding: someArg">DoSomethingWithArrayAndElement</button>
</div>
在这种情况下 customBinding
似乎产生:
- $data = 迭代中的当前元素
- $parent = 包含
People
数组的视图模型
- root = 与 $parent
相同
- $index = 迭代数组中的当前索引
- $parents = 包含视图模型的数组
我不确定这是否可行,但在没有进一步了解您的应用程序的情况下,这是我唯一可以建议的事情:创建一个公开完整数组的自定义 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
属性,从其中公开整个数组。
所以您的目标是让底层数组在 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>
我正在尝试制作要在 foreach 绑定中使用的自定义绑定,并且需要访问当前 observableArray
和 $data
.
现在我注意到 bindingContext
arg 包含 $data, $parent, $root
等,但是我似乎无法找到一种方法来访问正在迭代的数组,那么有什么办法吗?
为了清楚起见,这里有一个例子可以说明我的意思:
<div data-bind="foreach: People">
<button data-bind="customBinding: someArg">DoSomethingWithArrayAndElement</button>
</div>
在这种情况下 customBinding
似乎产生:
- $data = 迭代中的当前元素
- $parent = 包含
People
数组的视图模型 - root = 与 $parent 相同
- $index = 迭代数组中的当前索引
- $parents = 包含视图模型的数组
我不确定这是否可行,但在没有进一步了解您的应用程序的情况下,这是我唯一可以建议的事情:创建一个公开完整数组的自定义 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
属性,从其中公开整个数组。
所以您的目标是让底层数组在 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>