我刚刚升级到 knockout.js 2.2.0,并且 foreach 语句不再适用于计算的 observable。如果我切换回 2.1 它可以工作。计算出的 observable不会在下面的 html 中updatedValues
重新填充。foreach
请记住,下面的 html 是动态插入到单个 ajax 页面上的 dom 并应用绑定的。
ko.bindingHandlers.fields = {
init: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
app.viewModel.members.meta = {
values: ko.observableArray(value.values),
remove: function () {
app.viewModel.members.meta.values.remove(this);
return false;
},
add: function () {
app.viewModel.members.meta.values.push({ Name: '', Value: '', Index: ko.observable(app.viewModel.members.meta.values().length) });
return false;
},
max: value.max
};
app.viewModel.members.meta.updatedValues = ko.computed(function () {
if (this.values()) {
for (var i = 0; i < this.values().length; i++) {
if (this.values()[i].Index)
this.values()[i].Index(i);
else
this.values()[i].Index = ko.observable(i);
}
}
return this.values;
}, app.viewModel.members.meta);
}
};
<div class="control-group">
@Html.LabelFor(q => q, "Custom Fields")
<div class="controls">
<div class="meta" data-bind="fields: { values: @Model.Meta.OrderBy(q => q.Name).ToJSON(), max: @Model.MaxCount }">
<div data-bind="foreach: members.meta.updatedValues">
<div class="form-inline">
<div class="input-prepend">
<span class="add-on">Name</span>
@Html.TextBox("Key", string.Empty, new { maxvalue = "100", data_bind = "value: Name, attr: { name: '" + Model.PropertyName + "[' + Index() + '].Name', id: '" + Model.PropertyName + "[' + Index() + '].Name' }" })
</div>
@if(!Model.HideValues)
{
<div class="input-prepend">
<span class="add-on">Value</span>
@Html.TextBox("Value", string.Empty, new {data_bind = "value: Value, attr: { name: '" + Model.PropertyName + "[' + Index() + '].Value', id: '" + Model.PropertyName + "[' + Index() + '].Value' }"})
</div>
}
<a href="#" class="btn btn-mini btn-danger" title="Remove Field" data-bind="click: $parent.members.meta.remove"><i class="icon-minus icon-white"></i></a>
</div>
</div>
<div class="control-group">
@Html.Button("New Field", new { type="button", @class="btn", data_bind = "click: members.meta.add, visible: members.meta.max >= members.meta.values().length" })
@Html.Partial(MVC.Shared.Views.Controls.Help, new HelpModel { Url = Url.Action(Model.ActionResult ?? MVC.Members.Dashboard.CustomFieldsHelp()), Title = Model.Title ?? "Custom Fields" })
</div>
</div>
</div>
</div>