Knockout嵌套计算属性在页面加载时绑定,但在父计算属性更新后失败



我试图创建一个菜单,当您单击代表几个组之一的按钮时,会出现图像,显示最受欢迎的产品。我知道这可以做得更简单,但我正在尝试使用现有的数据模型。

我试图将img元素绑定到属性(ProductImageUrl),这是一个嵌套的ko.computed对象的属性(MostPopularProduct),这是一个父ko.computed对象的属性(SelectedGroup)。

viewModel.SelectedGroup().MostPopularProduct().ProductImageUrl

当页面加载时,一切都按预期工作,数据绑定到图像工作。但是,当我单击Group2按钮时,我得到以下数据绑定错误:

Uncaught TypeError: Unable to parse bindings.
Bindings value: attr:{src: SelectedGroup().MostPopularProduct().ProductImageUrl}
Message: undefined is not a function VM133:3

嵌套的ko.computed Property MostPopularProduct()有一个值,并且在页面加载时正确绑定,但是在单击按钮之后,在父Computed Property更新之后,嵌套的ko.computed Property MostPopularProduct()是未定义的。

我怀疑这个问题与viewModel属性的数据绑定有关,该属性是嵌套的ko.computed属性的属性。

代码如下:http://jsfiddle.net/boaldave/n5KQr/9/

<div id="GroupSelector">
    <img data-bind="attr:{src: SelectedGroup().MostPopularProduct().ProductImageUrl}">
    <ul id="Menu" data-bind="foreach:Groups">
        <li>
            <button data-bind="click: $parent.HandleButtonClick">
                <span data-bind="text: $data.GroupName"></span>
            </button>
        </li>
    </ul>
</div>
<script>
viewModel = {
    Groups: 
    [
        {
            GroupName:"Group1",
            MostPopularProductID: "Product1"
        },
        {
            GroupName:"Group2",
            MostPopularProductID: "Product2"
        }
    ],
    Products:
    [
        {
            ProductID: "Product1",
            ProductImageUrl: "http://placehold.it/100x100"
        },
        {
            ProductID: "Product2",
            ProductImageUrl: "http://placehold.it/200x200"
        }
    ]
};
// Since the data model above comes from a database, I extend the 
// viewModel properties with ko.observable and ko.computed properties:
viewModel.SelectedGroupName = ko.observable("Group1");
viewModel.SelectedGroup = ko.computed(function() {
    return ko.utils.arrayFirst(viewModel.Groups, function(item) {
        return item.GroupName === viewModel.SelectedGroupName();
        });
    }, viewModel);
viewModel.SelectedGroup().MostPopularProduct = ko.computed(function ()  {
    return ko.utils.arrayFirst(viewModel.Products, function (item) {
        return item.ProductID === viewModel.SelectedGroup().MostPopularProductID;
        });
    }, viewModel);
viewModel.HandleButtonClick = function(s, e) {
    viewModel.SelectedGroupName(s.GroupName);
};
var groupSelectorDiv = document.getElementById('GroupSelector');
if (groupSelectorDiv) {
    ko.applyBindings(viewModel, groupSelectorDiv);
}
</script>

JSFiddle: http://jsfiddle.net/jhmRc/

尝试改变

viewModel.SelectedGroup().MostPopularProduct = ko.computed(function ()  {

viewModel.SelectedGroup.MostPopularProduct = ko.computed(function ()  {

并更改

<img data-bind="attr:{src: SelectedGroup().MostPopularProduct().ProductImageUrl>

<img data-bind="attr:{src: SelectedGroup.MostPopularProduct().ProductImageUrl}>

在您的示例中,您将MostPopularProduct分配给computed的值,这就是为什么它在页面加载时工作,而不是在值更改后工作。

第二种方法是将它添加到计算对象本身

最新更新