【问题标题】:KnockoutJS Binding a list of objects from an AJAX callKnockoutJS 绑定来自 AJAX 调用的对象列表
【发布时间】:2016-05-22 11:16:29
【问题描述】:

我的 Javascript 代码中有一个数据对象,描述如下:

    //Data Object that represents products
    function Product(n, p, t, d) {
        this.name = ko.observable(n);
        this.price = ko.observable(p);
        tags = typeof (t) !== 'undefined' ? t : [];
        this.tags = ko.observableArray(tags);
        discount = typeof (d) !== 'undefined' ? d : 0;
        this.discount = ko.observable(discount);
        this.formattedDiscount = ko.computed(function ()
        { return (this.discount() * 100) + "%"; }
                                 ,this);
    }

然后,我有一个 AJAX 调用来检索 JSON 格式的数据

 $(document).ready(function () {
         $.ajax({
             type: "POST",
             url: "ShoppingCartExampleExample.aspx/SendData",
             data: "{}",
             contentType: "application/json; charset=utf-8",
             dataType: "json",
             success: function (msg) {
                 alert(msg.d);               
             }
         });
     });

AJAX 调用正常,结果如下:

[
 {"Discount":0,
  "Name":"Chocolate",
  "Price":"7.99"
  "tags": ["Mars","Snickers"]
 },
 {"Discount":0.05,
  "Name":"Beer",
  "Price":"3.99"
 "tags": ["Large","Extra"]
 }
]

如何将从 AJAX 调用接收到的对象列表映射到我的数据对象? 我想将此列表映射到可观察数组,并将标签数组映射到可观察数组,因为我有一个 foreach 绑定,它填充 HTML 表以显示产品和标签。

谢谢

【问题讨论】:

    标签: javascript json ajax knockout.js


    【解决方案1】:

    Knockout utility functions 现在包含在最新版本中,是我处理事情的首选方式。映射插件有时会被过度使用,如果使用不当,可能会使您的对象变得过于臃肿。

    当你的对象数组被返回时,使用实用程序类:

    var newProducts = ko.utils.arrayMap(data, function(dataItem) {
        return new Product(...);
    });
    
    ko.utils.arrayPushAll(myViewModel.products, newProducts);
    

    非常直接且受支持。您甚至可以将 arrayMap 作为第二个参数直接放入 arrayPushAll 并跳过声明 newProducts 变量。

    【讨论】:

      【解决方案2】:

      所以假设在您的 success 函数中 msg.d 是您的数组。只需循环遍历数组并为每个项目调用new Product,然后将结果推送到父视图模型的可观察数组中。例如,如果你有类似的东西:

      var rootViewModel = function() {
          this.products = ko.observableArray();
          //... whatever other properties and functions you have
      }
      
      var myViewModel = new rootViewModel();
      

      然后在您的 ajax 调用的 success 函数中,您会执行以下操作:

      success: function (msg) {
          msg.d.forEach(function(item) {
              myViewModel.products.push(new Product(item.Name, item.Price, item.tags. item.Discount));
          }             
      }
      

      使用mapping 插件可以避免其中的一些问题,该插件非常可配置,允许您将纯javascript 对象从您的ajax 调用映射到您想要的任何视图模型。

      【讨论】:

        猜你喜欢
        • 2013-08-03
        • 2017-10-10
        • 2020-05-05
        • 1970-01-01
        • 2020-01-24
        • 2013-05-26
        • 2013-11-21
        • 1970-01-01
        • 2013-06-24
        相关资源
        最近更新 更多