2

我已经使用 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 来解决它。但是我认为必须远离淘汰赛?

4

2 回答 2

2

你很亲近!我添加了ko.utils.unwrapObservable调用,因为我打赌 funkyThingID 是一个可观察的,而不仅仅是一个直接的属性——你自己在你的selectFunkyThing函数中做了这个。你也可以执行它们。不过,我喜欢 unwrap 的冗长。

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)}">
于 2013-03-15T21:12:17.347 回答
1

这些属性不是都可观察的,所以您需要将它们作为函数引用吗?我认为,您还需要使您的函数成为计算的 observable:

model.isSelected = ko.computed(function (funkyThing) {
    return funkyThing().funkyThingID() == model.selectedFunkyThing().funkyThingID();
});
于 2013-03-15T18:11:25.270 回答