将新项目推送到knockout observableArray后,HTML表格不会更新

时间:2015-02-06 17:18:06

标签: javascript knockout.js

我无法更新HTML用户界面。

当文档加载并调用" getAllProducts()"时,HTML UI会显示我的所有项目,并使用正确的css类来显示' styleStatusCss'和右边的' ; displayName',问题是,当我尝试使用新更新的产品更新我的observableArray时(产品名称或状态已更改),html用户界面不会更新并保持不变

所以这里是正在发生的事情的快速列表:

    每隔25秒调用
  • getUpdatedProducts(),并返回任何产品 已更新
  • 我检查了我的可观察数组有多少产品:appVM.itemList.length它确实有100个(正如预期的那样!),我还检查已发回的json产品是否有一些修改后的数据,确实已经改变了!
  • 然后我使用该产品json对象
  • 创建javascrip obj MyProduct
  • 现在我将我新创建的javascript obj MyProduct添加到observablearray:appVM.itemList.push(newUpdatedProduct);
  • 最后我检查了我的observablearray在推送后有多少项,(因为我在HTML UI上看不到任何变化),appVM.itemList.length现在说101 !!!怎么可能? HTML UI仍然显示初始加载后的数据

请参阅以下大部分代码

HTML

<table >
        <tbody data-bind="foreach: itemList">
            <tr>
                <td>
                    <div data-bind="css: styleStatusCss"></div>
                </td>
                <td>
                     <div data-bind="text: displayName"></div>
                </td>
            </tr>
            </tbody></table>

这是javascript:

<script type="text/javascript">
    var appVM;
    var initializeItems = false;

    $.ajaxSetup({
        // Disable caching of AJAX responses
        cache: false
    });



    $(document).ready(function () {
        getAllProducts();

    });

    setInterval(function () {
        if (initializeItems) {
            getUpdatedProducts();
        }
    }, 25000);



  function getAllProducts() {

        var url = '@Url.Action("_AllProducts", "Home")';
        $.ajax({
            url: url,
            type: 'GET',
            dataType: 'JSON',
        })
        .success(function (result) {
            initializeItems = true;
            appVM = new AppViewModel();
            var mappedProducts = ko.utils.arrayMap(result.ItemList, function (item) {
                var con = new MyProduct(item);
                return con;
            });
            appVM.itemList = mappedProducts;
            ko.applyBindings(appVM);
        })
        .error(function (xhr, status, error) {
            alert("FATAL ERROR");
        })


  }

  function getUpdatedProducts() {
      var url = '@Url.Action("_UpdateProducts", "Home")';
      $.ajax({
          url: url,
          type: 'GET',
          dataType: 'JSON',
      })
      .success(function (result) {
          if (result.HasNewData) {
              alert("we have some data");
              alert("START COUNT: " + appVM.itemList.length); //this shows all my 100 products -> START COUNT: 100
              alert("Number of new items: " + result.ItemList.length); // i only get one product back for easy debugging
              for (index = 0; index < result.ItemList.length; ++index) { 

                  var updatedProdJson = result.ItemList[index]; //get the json for the product
                  alert("New prod json: " + objToString(updatedProdJson)); //just for debugging print out in a readable format

                  var newUpdatedProduct = new MyProduct(updatedProdJson);//create our MyProduct object (which has all properties as observable)

                  appVM.itemList.push(newUpdatedProduct); //add our new MyProduct to the list

          alert("FINAL COUNT: " + appVM.itemList.length); // --> FINAL COUNT: 101

              }
          }
      })
      .error(function (xhr, status, error) {
          alert("Error: " + status);
      })
  }





 function AppViewModel() {
      var self = this;  //so it references the viewModel object 
      self.itemList = ko.observableArray([]);

      self.doAlert = function () {
          alert("HERE");
      }
  }



   function MyProduct(data) {
       //alert("DATA: " + objToString(data));
       this.Id = ko.observable( data.Id);
       this.Name = ko.observable(data.Name);
       this.status =  ko.observable(data.Status);

       this.displayName = ko.computed(function () {
           var fullnmae = this.Id() + " " + this.Name();
           return fullnmae;

       }, this);
       this.styleStatusCss = ko.computed(function () {
           var pStatus = 'divstatusnone';
           if (this.status() === 'H')
               pStatus = 'divlowstatus';
           if (this.status() === 'D')
               pStatus = 'divhighstatus';
           return pStatus;
       },this);
   }

   function objToString (obj) {
       var str = '';
       for (var p in obj) {
           if (obj.hasOwnProperty(p)) {
               str += p + '::' + obj[p] + '\n';
           }
       }
       return str;
   }

希望有人能告诉我哪里出错了。

非常感谢,

1 个答案:

答案 0 :(得分:2)

在getAllProducts中

,您将结果分配给itemList,丢失了您的可观察数组:

appVM.itemList = mappedProducts;

你需要这样做:

appVM.itemList(mappedProducts);