我使用ko.mapping.fromJS(Model)将一个ASP.NET MVC viewModel加载到KnockoutJS中。
我的viewModel看起来像这样:
public IEnumerable<FunkyThing>funkyThings;
public FunkyThing selectedFunkyThing;
然后,我在HTML视图中找到了一个类似于
的表格<tbody data-bind="foreach: funkyThings">
<tr>
<td data-bind="text:name"></td>
<td data-bind="text:funkiness"></td>
<td><a href='#' title="Select Funky Thing" data-bind="click: $root.selectFunkyThing"></a>
</td>
</tr>
</tbody>
这张桌子的一切都很好。单击select funky thing链接可以快速调用selectFunkyThing函数:
model.selectFunkyThing= function (funkyThing) {
window.location = '@Url.Action(MVC.FunkyThingController.Index())' + "?funkyThingID=" + funkyThing.funkyThingID();
};
反过来刷新页面。重新加载MVC视图模型,并使用所选的FunkyThing填充selectedFunkyThing,然后从MVC视图模型重新读取挖空视图模型。到目前为止一切都很好。
然后我想更新表格以突出显示所选条目。 所以我按如下方式更新了tr行:
<tr data-bind="css:{'selected': $root.isSelected()}">
并创建了新的淘汰赛功能:
model.isSelected = function (funkyThing) {
return funkyThing.funkyThingID== model.selectedFunkyThing.funkyThingID;
};
但......它不起作用。 Chrome会抛出一个javascript异常,指出FunkyThing参数未定义。 从技术上讲,我想通过更改MVC viewModel来实现在数组中的每个FunkyThing上实际设置isSelected来解决它。但是我觉得必须要从Knockout那里做到这一点?
答案 0 :(得分:2)
你很亲密!我添加了ko.utils.unwrapObservable
调用,因为我打赌funkyThingID是一个可观察的而不仅仅是一个直接的属性 - 你自己在selectFunkyThing
函数中做到了这一点。你也可以执行它们。我喜欢解开的详细信息。
model.isSelected = function (funkyThing) {
var thisId = ko.utils.unwrapObservable(model.selectedFunkyThing.funkyThingID);
return ko.utils.unwrapObservable(funkyThing.funkyThingID) == thisId;
};
然后在你的文档中,当ko解析绑定
时,你实际上必须执行这个函数<tr data-bind="css:{'selected': $root.isSelected($data)}">
答案 1 :(得分:1)
这些属性是否都不是可观察的,所以你需要将它们作为函数引用?您还需要使您的函数成为计算的可观察函数,我认为:
model.isSelected = ko.computed(function (funkyThing) {
return funkyThing().funkyThingID() == model.selectedFunkyThing().funkyThingID();
});