【问题标题】:loading a knockout.js observableArray() from .ajax() call从 .ajax() 调用加载一个 knockout.js observableArray()
【发布时间】:2012-04-01 14:18:57
【问题描述】:

这让我很困惑。它一定是我没看到的小东西。我正在尝试通过 ajax 调用在淘汰赛中加载一个非常简单的 observableArray

javascript

// we bind the array to the view model property with an empty array.
var data = [];   
var viewModel = {
    vendors: ko.observableArray(data)
};
ko.applyBindings(viewModel);

$(function () {
    // on this click event, we popular the observable array
    $('#load').click(function () {
        // WORKS. Html is updated appropriately.
        viewModel.vendors([{ "Id": "01" },{ "Id": "02" },{ "Id": "03" }]);

        // DOES NOT WORK. Fiddler2 shows the same exact json string come back 
        // as in the example above, and the success function is being called.
        $.ajax({
            url: '/vendors/10',
            dataType: 'json',
            success: function (data) {
                viewModel.vendors(data);
            }
        });
    });
});

html

<button id="load">Load</button>
<ul data-bind="template: { foreach: vendors }">
    <li><span data-bind="text: Id"></span></li>
</ul>

问题:为什么ajax调用成功,谁的data变量值逐字节匹配硬类型值,而不触发html刷新?

【问题讨论】:

    标签: javascript json ajax knockout.js


    【解决方案1】:

    没有理由这不能正常工作。如上所示。

    http://jsfiddle.net/madcapnmckay/EYueU/

    我会检查 ajax 帖子实际上是否返回了 json 数据,并且该 json 是一个数组并且它被正确解析。

    我必须调整 ajax 调用以使 fiddle ajax 处理程序正常工作。

    我想不出更多了。

    希望这会有所帮助。

    【讨论】:

    • 感谢您验证我的理智......我会再仔细看看。也许 MVC 吸收了一个小包装器或其他东西......
    • 是的。 Firebug 请求响应,验证您正在获取 json,然后验证 jquery 正在将其解析为对象。
    • 它肯定是 json...C# 代码看起来像 return Json(list, JsonResponseBehavior.AllowGet); 其中 list 是 ICollection` 所以我知道它是 JSON。除此之外,Fiddler2 正确地在其 JSON 视图中显示数据......它在某个地方的 javascript 中。明天上班时我会再次发布更多信息
    【解决方案2】:
    var self=this;
    //var self first line in model
    
    $.ajax({
                url: ",
                dataType: "json",
                contentType: 'application/json',
                type: "POST",
                data: JSON.stringify({ }),
                processdata: true,
    
                beforeSend: function () {
                    $.mobile.loading('show');
                },
    
                error: function (xhr, textStatus, errorThrown) {
                    alert('Sorry!');
                },
    
                success: function (data) {
    
                    $.mobile.loading('hide');
                    if (data.result!= '') {
                        self.vendors(data.result);
    
    
    
                    } else {
                        self.vendors({something});
    
                    }
                }
            });
    

    使用 self.vendors 而不是这个 viewModel.vendors

    【讨论】:

      【解决方案3】:

      这是我在 MVC .net 应用程序中使用 knout 和 jquery 所做的。

      // Scripts/groItems.js
      (function () {
      
          var ViewModel = function () {
              items = ko.observableArray(),
                  ItemName = ko.observable(),
                  Img = ko.observable(),
                  Qty = ko.observable()
          }
      
          $.getJSON('/Items2/AllItems', function (data) {
              for (var i = 0; i < data.length; i++) {
                  self.items.push(data[i]);
              }
          });
      
          var vm = new ViewModel();
      
          $(function () {
              ko.applyBindings(vm);
          });
      
      }());
      @model IEnumerable<GroModel.Item>
      @{
          ViewBag.Title = "Index";
      }
      
      <p>
          @Html.ActionLink("Create New", "Create")
      </p>
      
      <div data-bind="text: items().length"></div>
      <table class="container table table-hover">
          <thead>
              <tr>
                  <th>Item name</th>
                  <th>img</th>
                  <th>qty</th>
              </tr>
          </thead>
          <tbody data-bind="foreach: items">
              <tr>
                  <td data-bind="text: ItemName"></td>
                  <td data-bind="text: Img"></td>
                  <td data-bind="text: Qty"></td>
              </tr>
          </tbody>
      </table>
      
      @section Scripts {
          <script src="~/Scripts/knockout-3.4.2.js"></script>
          <script src="~/Scripts/groItems.js"></script>
      }

      以下是我在 Items2Controller.cs 中的代码的一部分

          private GroContext db = new GroContext();
          public JsonResult AllItems()
          {
              return Json(db.Items.ToList(), JsonRequestBehavior.AllowGet);
          }
      

      希望这会有所帮助。谢谢

      【讨论】:

        【解决方案4】:

        我们可以使用一个简单的 JavaScript util 函数作为解决方法。

        代替viewModel.vendors(data);,使用 eval 包装(首先研究 eval 的危险)会起作用。

        eval("viewModel.vendors("+JSON.stringify(data)+");");
        

        【讨论】:

        【解决方案5】:

        我认为这是错误,当我们将 Knockout 的示例与包装类一起使用时,它正在工作:

        public class ResultWrapper
        {
            public Title {get;set;}
            public List<Result> {get;set;}
        }
        

        http://learn.knockoutjs.com/#/?tutorial=webmail

        但是如果我们直接返回 Results 是没有办法绑定的。 (没有额外的 applyBindings!)

        【讨论】:

          猜你喜欢
          • 2016-02-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多