【问题标题】:knockout dynamic binding issue淘汰赛动态绑定问题
【发布时间】:2013-03-06 23:53:39
【问题描述】:

考虑以下通过敲除映射插件生成的 ViewModel。

var originalData = {

"QuoteSelectedViewModel": {
  "ProductName": "Select",      
  "CoverQuotesViewModel": [
     {
        "Code": 1,
        "Label": "Première Assistance 24h/24 (GRATUITE)",
        "IsMandatory": true,
        "IsSelected": true,            
        "DependsOn": []
     },
     {
        "Code": 2,
        "Label": "Assistance PLUS 24h/24",
        "IsMandatory": false,
        "IsSelected": false,          
        "DependsOn": []
     },
      {
        "Code": 8,
        "Label": "Heurts Animaux / Force de la Nature",
        "IsMandatory": false,
        "IsSelected": false,        
        "DependsOn": [
           2
        ]
     },
  ]}
}

var viewModel = ko.mapping.fromJS(originalData);

ko.applyBindings(viewModel);


<div data-bind="with: QuoteSelectedViewModel">
selected quote is : <span data-bind="text: ProductName"></span>
 <!-- ko foreach: CoverQuotesViewModel -->
<br/>    
  <div data-bind: if: IsVisible>
    <input type="checkbox" data-bind="checked: IsSelected"></input>
    <input type="text" data-bind="value: Label, enable: IsSelected"></input>
  </div>
<!-- /ko -->
</div>

现在,我想在 IsVisible 返回 false 时隐藏 div。 IsVisible 尚不存在,它应该是 CoverQuotesViewModel 数组的每个元素上的计算 observable 函数。

如何在每个元素上生成这个计算出的 observable 函数?

谢谢

[编辑] 我在这里添加了一个 jsfiddle:http://jsfiddle.net/graphicsxp/fpKWM/

[编辑2] 实际上淘汰赛文件很清楚如何做到这一点:

当然,在创建回调中,您可以再次调用 ko.mapping.fromJS 如果你愿意的话。如果您愿意,一个典型的用例可能是 用一些额外的东西来扩充原始的 JavaScript 对象 计算的可观察量:

var myChildModel = 函数(数据){ ko.mapping.fromJS(data, {}, this);

this.nameLength = ko.computed(function() {
    return this.name().length;
}, this); }

[编辑]

以下是按照 Paul 建议的完整代码: (getQuotesSuccess 是一个 AJAX 成功处理程序)

viewModel.getQuotesSuccess = function (result) {
var myCoverQuotesViewModel = function (data, parent) {
    var self = this;
    ko.mapping.fromJS(data, {}, this);

    self.IsVisible = ko.computed(function () {
        var visible = true;
        if (self.DependsOn().length > 0) {
            $.each(self.DependsOn(), function (index, value) {
                var dependency = viewModel.QuoteSelectedViewModel().CoverQuotesViewModel.filterByProperty("Code", value);
                if (dependency().length > 0) {
                    visible = visible & dependency()[0].IsSelected();
                } else {
                    visible = false;
                }
            });
        }

        return visible;

    }, this);
}

var mapping = {
    'CoverQuotesViewModel': {
        create: function (options) {
            return new myCoverQuotesViewModel(options.data, options.parent);
        }
    }
}

  ko.mapping.fromJS(result, mapping, viewModel);
};

【问题讨论】:

  • 您希望 IsVisible 执行什么逻辑?
  • 让我们假设 IsVisible 的逻辑与问题无关。它应该返回真或假。问题是我不知道如何在数组的每个元素上动态生成这个计算的 observable 函数。
  • 查看我的答案,了解如何遍历数组中的每个对象。这不是你所追求的吗?

标签: binding knockout.js


【解决方案1】:

好的,通过您的修改恢复到我之前的答案,因此其他任何查看此答案的人实际上都会得到正确的版本!

您需要创建一个子 viwe 模型,并使用映射插件自动填充它,然后添加您的计算 observable:

function CoverQuotesViewModel(data)
{
    var self = this;
    ko.mapping.fromJS(data, {}, self);

    // Copy the data to each property.
    self.IsVisible = ko.computed(function()
    {
            // your logic for each quote
    });
}

然后你需要使用create map来映射主视图模型,并在此创建你的子视图模型:

var mapping = {
    'CoverQuotesViewModel': {
        create: function(options) {
            var model = new CoverQuotesViewModel(options.data);
            return model;
        }
    }
}
var viewModel = ko.mapping.fromJS(data, mapping);

您不需要将this 传递到计算中,因为您引用的是 self,这是您存储的 this 版本。

【讨论】:

  • IsVisible 函数应该在数组的每个元素上创建,而不是在根级别。
  • 太好了,它按预期工作。但是,必须手动映射所有剩余的属性非常不方便。有什么办法可以在手动添加 IsVisible 计算的 observable 时保持自动映射?
  • 你可以试试这个更新的答案,虽然我不知道这是否可行!
  • 谢谢,但它不起作用。 IsVisible 属性已正确添加到 CoverQuotesViewModel,但所有其他属性都消失了。知道我能做什么吗?
  • 嗯,根据文档 (knockoutjs.com/documentation/plugins-mapping.html),它应该可以工作。我认为您需要将其他属性添加到 CoverQuotesViewModel 类中,您这样做了吗?
猜你喜欢
  • 2014-09-18
  • 2013-01-09
  • 2016-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-17
  • 2013-10-08
相关资源
最近更新 更多