HTML表未更新,在将新项推送到knocketinobservableArray之后

HTML table not updating, after pushing new item to knockout observableArray

本文关键字:新项推 knocketinobservableArray 之后 更新 HTML      更新时间:2023-09-26

我在更新HTML UI时遇到问题。

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

下面是正在发生的事情的快速列表:

  • getUpdatedProducts()每25秒调用一次,并返回任何乘积已更新
  • 我检查了我的可观察数组有多少个产品:appVM.itemList.length,它确实有100个(正如预期的那样!),我还检查了发送回来的json产品是否有一些修改的数据,实际上它已经更改了
  • 然后,我使用该产品json对象创建javascrip obj MyProduct
  • 现在,我将新创建的javascript obj MyProduct添加到observalearray:appVM.itemList.prush(newUpdatedProduct)
  • 最后,在推送之后,我检查了我的observalearray有多少项(因为我在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;
   }

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

非常感谢,

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

appVM.itemList = mappedProducts;

你需要这样做:

appVM.itemList(mappedProducts);