【问题标题】:KnockoutJS - Adding computed values to an observable arrayKnockoutJS - 将计算值添加到可观察数组
【发布时间】:2012-03-13 06:50:42
【问题描述】:

我正在使用 KnockoutJS 将数据绑定到页面,ViewModel 由来自使用 mapping plugin 的 AJAX 调用的 JSON 响应填充,如下所示:

$(function () {
    $.getJSON("@Url.Action("Get")", 
        function(allData) {
            viewModel = ko.mapping.fromJS(allData);

            viewModel.Brokers.Url = ko.computed(function()
            {
                return 'BASEURLHERE/' + this.BrokerNum();
            });

            ko.applyBindings(viewModel);
    });
});

中间部分不起作用(没有该计算属性它可以正常工作)。 “经纪人”是一个可观察的数组,我想为数组中称为 URL 的每个元素添加一个计算值。我将该 Brokers 数组绑定到一个 foreach,并且我想将该 URL 用作锚点的 href 属性。有什么想法吗?

【问题讨论】:

    标签: javascript mvvm knockout.js knockout-mapping-plugin


    【解决方案1】:

    我一直在解决非常相似的问题,我发现您可以拦截 Broker 对象的创建并使用映射选项参数插入您自己的字段:

    var data = { "Brokers":[{"BrokerNum": "2"},{"BrokerNum": "10"}] };
    
    var mappingOptions = {
        'Brokers': {
            create: function(options) {
                return (new (function() {
                    this.Url = ko.computed(function() {
                        return 'http://BASEURLHERE/' + this.BrokerNum();
                    }, this);
    
                    ko.mapping.fromJS(options.data, {}, this); // continue the std mapping
                })());
            }
        }
    };
    
    viewModel = ko.mapping.fromJS(data, mappingOptions);
    
    ko.applyBindings(viewModel);
    

    这里有一个小提琴来证明这一点:http://jsfiddle.net/pwiles/ZP2pg/

    【讨论】:

      【解决方案2】:

      好吧,如果你想在每个代理中添加 Url,你必须将它添加到每个代理中:

      $.each(viewModel.Brokers(), function(index, broker){
          broker.Url = ko.computed(function(){return 'BASEURLHERE/' + broker.BrokerNum();});
      });
      

      我猜BrokerNum是不会变的,所以你还不如只计算一次Url:

      $.each(viewModel.Brokers(), function(index, broker){
          broker.Url = 'BASEURLHERE/' + broker.BrokerNum();
      });
      

      您还可以通过向 ko.mapping.fromJS 函数提供“create”回调来在映射期间添加 Url 属性。详情请见mapping plugin docs

      如果只需要url绑定href,只需绑定html中的表达式(在foreach绑定内):

      <a data-bind="attr: {href: 'BASEURLHERE/' + BrokerNum()}">link to broker details</a>
      

      【讨论】:

        【解决方案3】:

        感谢 Peter Wiles,我有非常相似的解决方案:

        var ViewModel = function (data, ranges) {
            var self = this;
        
            this.productList = ko.observableArray();
            var productListMapping = {
                create: function (options) {
                    return (new (function () {
                    //this row above i don't understand...
                        this.len = ko.computed(function () {
                            //just test function returning lenght of object name
                            // and one property of this model
                            return this.name().length + ' ' + self.cons_slider_1();
                        }, this);
        
                        ko.mapping.fromJS(options.data, {}, this); // continue the std mapping
                    })());
                }
            }
        
            this.cons_slider_1 = ko.observable(100);
        
            ko.mapping.fromJS(data, productListMapping, this.productList);
        };
        

        一些区别: 我不是映射到自我,而是映射到 this.product。 在上面的例子中,输入的 json 没有像“经纪人”这样的父名称:

        var products = [
            { "id": "pp1", "name": "Blue windy" },
            { "id": "pp1", "name": "Blue windy" }];
        

        所以在 productMapping 中我只输入“create:”

        但是,我不明白的是 create 函数的结构。有人可以解释一下为什么该函数返回具有属性的新函数。不能以某种方式简化吗?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-13
          • 2013-05-23
          • 2012-04-20
          • 1970-01-01
          • 1970-01-01
          • 2014-07-06
          • 1970-01-01
          相关资源
          最近更新 更多