【问题标题】:Knockout Observable Array Length always 0Knockout Observable Array Length 始终为 0
【发布时间】:2013-03-11 10:41:38
【问题描述】:

在 customerOverview 视图模型中调用任何可观察对象的长度时,我收到的长度为零。当绑定随数据更新时,可观察对象中存在数据,但长度保持为 0。基本视图模型“CustomerCentral”正确返回长度。我需要 'CustomerOverview' 中一些 observables 的长度来做一些条件语句。

HTML 绑定

<ul class="nav nav-list">
      <li class="nav-header">Contacts</li>
      <!--ko  if: customerOverview.contacts().length == 0-->
      <li>No contacts associated with this customer</li>
       <!-- /ko -->
      <!--ko  foreach: customerOverview.contacts()-->
      <li>
      <a data-bind="click: $root.customerOverview.viewContact"><i class="icon-chevron-                        right single pull-right">
       </i><span data-bind="text: FirstName"></span><span data-bind="text: LastName"></span>
      </a></li>
      <!-- /ko -->
</ul>

JS

function CustomerOverview() {
        var self = this;        

        self.contacts = ko.observableArray([]);           

        self.getCustomerContacts = function () {
            requestController = "/CRM/CustomerCentral/CustomerContacts";
            queryString = "?id=" + self.customer().Id();
            $.ajax({
                cache: false,
                type: "GET",
                dataType: "json",
                url: baseURL + requestController + queryString,
                headers: { "AuthToken": cookie },
                success:
                        function (data) {
                            if (data.data.length > 0) {

                                self.contacts(ko.mapping.fromJS(data.data));

                                console.log(self.contacts().length);
                            }
                        }
            });
        };
};
   function CustomerCentral() {

        var self = this;

        self.customerOverview = ko.observable(new customerOverview());
};

var vm = new CustomerCentral();
    ko.applyBindings(vm);

控制台 cmd:vm.customerOverview().contacts().length 0

---------------解决方案------- --- observableArray.push()

问题原来是这一行:

  self.contacts(ko.mapping.fromJS(data.data));

解决方案: 向其中添加 .push() 可以增加数组的长度属性。我曾假设 ko.mapping 会处理这个问题,但事实并非如此。将变量更改为 observable 没有效果。

 $.each(data.data, function () {
          self.contacts.push(ko.mapping.fromJS(this));
           console.log(self.contacts().length);
                                    });

【问题讨论】:

    标签: javascript html knockout.js mapping ko.observablearray


    【解决方案1】:

    我认为您的问题在于您的 customerOverview 属性无法观察到

    尝试:

     self.customerOverview = ko.observable(new CustomerOverview());
    

     self.customerOverview = ko.computed(function(){
           return new CustomerOverview();
     });
    

    工作示例:

    http://jsfiddle.net/dvdrom000/RHhmY/1/

    html

    <span data-bind="text: customerOverview().contacts().length"></span>
    <button data-bind="click: customerOverview().getCustomerContacts">Get contacts</button>
    

    js

    function CustomerOverview() {
            var self = this;        
    
            self.contacts = ko.observableArray([]);           
    
            self.getCustomerContacts = function () {
                self.contacts.push(1);
                self.contacts.push(2);
                self.contacts.push(3);            
            };
    };
       function CustomerCentral() {
    
            var self = this;
            // Is this a correct way. Am I breaking something with this?
            self.customerOverview = ko.observable(new CustomerOverview());
    };
    
    var vm = new CustomerCentral();
        ko.applyBindings(vm);
    

    【讨论】:

    • 两者都实现了,但无济于事。长度保持为 0。我认为您走在正确的道路上,使其可观察到,我会保留此更改,但我仍然需要解决零长度问题。
    • 此示例确实有效,但它使用的是 .push() 而不是 ko.mapping.fromJS()。从那以后我尝试的是语句 self.contacts.push(ko.mapping.fromJS(data.data)); // 这给了我一个长度。我现在需要做的就是弄清楚这些数据是如何嵌套在联系人中的。
    • 感谢您抽出宝贵时间 Roman,此问题已解决。 observable 没有任何效果,但结果是 .push()。包括这使得数组的长度能够增加。我假设 ko.mapping 会自己处理长度。问题已编辑,已发布解决方案和解决方案。
    【解决方案2】:

    Knockout 为数组提供了一组操作函数 镜像 JavaScript 中的函数;流行,推,转移, 取消移位、反转、排序和拼接。随着执行 您期望的操作,这些数组函数也会自动 通知任何观察者该数组已更改。 JavaScript 方法不会。如果您希望您的 UI 在数组计数时更新 更改,您需要小心使用 Knockout 功能。

    参考:http://ryanrahlf.com/knockout-js-observablearray-not-updating-the-ui-heres-how-to-fix-it/

    所以基本上,要解决你的问题,你只需要直接在可观察数组上使用敲除推送功能,而不是使用 javascript 推送方法。因此:

    改变这个:

    self.contacts( ).push( data.data );
    

    通过这个:

    self.contacts.push( data.data );
    

    您将能够在您的 html 上使用 contacts( ).length 属性,并在数组中的每一次更改时收到通知。

    【讨论】:

      【解决方案3】:

      observableArray.push()

      问题原来是这一行:

      self.contacts(ko.mapping.fromJS(data.data));
      

      解决方案:添加 .push() 可以使数组的长度属性增加。我曾假设 ko.mapping 会处理这个问题,但事实并非如此。将变量更改为 observable 没有效果。

      $.each(data.data, function () {
                self.contacts.push(ko.mapping.fromJS(this));
                 console.log(self.contacts().length);
                                          });
      

      【讨论】:

        【解决方案4】:

        我遇到了这样的问题,IIRC,这是因为我在评论条件中使用双等号 (==) 而不是三等号 (===)。试一试。

        【讨论】:

        • 很有趣,感谢您的意见。然而,这与我的问题无关,因为在过去的条件语句中,我已经毫无问题地实现了双重和三重。零长度仍然存在。
        【解决方案5】:

        代替:

        self.contacts(ko.mapping.fromJS(data.data));
        

        你应该有:

        self.contacts(ko.mapping.fromJS(data.data)**()**);
        

        【讨论】:

          猜你喜欢
          • 2017-12-13
          • 2013-04-22
          • 1970-01-01
          • 1970-01-01
          • 2014-10-01
          • 2014-11-27
          • 1970-01-01
          • 2013-11-10
          • 2012-06-14
          相关资源
          最近更新 更多