Knockout-Kendo listview在valueHasMutated之后没有初始化

Max*_*ido 7 kendo-ui knockout.js knockout-kendo

我正在开发一个项目,要求我使用Kendo UI和Knockout.js作为移动应用程序,作为一种绑定这些库的方法我正在使用knockout-kendo库,该应用程序包含一个简单的产品列表每个产品和购物车的详细视图,但是我在更新购物车中的商品数量时遇到了一些问题.

我在我的应用程序中使用knockout-kendo绑定如下:

<div data-role="view" id="cart" data-title="Cart" data-layout="main-layout">
    <div data-bind="if: items().length == 0">No items currently in cart</div>
    <ul data-role="listview" data-style="inset" data-bind="kendoListView: { data: items, template: cartTemplate }"></ul>
</div>
Run Code Online (Sandbox Code Playgroud)

模板的位置是:

<script type="text/x-kendo-template" id="cartListTemplate">
    <div class="km-listview-link cart-item-container" data-id="#= Id #">
      <div class="product-image">
      <img src="#= ImageUrl #">
    </div>
    <div class="product-description">
      <p>#= Name #</p>
      <p>#= formattedPrice #</p>
      <p>#= quantity #</p>
    </div>
    <a data-role="button" data-icon="delete" class="km-primary" data-bind="click: removeItem">Delete</a>
  </div>
</script>
Run Code Online (Sandbox Code Playgroud)

而ViewModel是:

CartViewModel : function () {
        var self = this;
        globalKo.cartItems = self.items = ko.observableArray(JSON.parse(localStorage.getItem('cart')) || []);
        self.cartTemplate = kendo.template($('#cartListTemplate').html());
        self.removeItem = function (vm, event) {
            var element = $(event.target).parents('div.cart-item-container');
            productId = element.data('id');
            var cartItem = globalKo.cartItems().filter(function (element) {
                return element.Id == productId;
            })[0];
            if (cartItem.quantity > 1) {
                cartItem.quantity --;
            } else {
                self.items.remove(cartItem);
            }
            app.saveCart(); 
            self.items.valueHasMutated(); 
        }
    }
Run Code Online (Sandbox Code Playgroud)

它显然按预期工作,除了当数组值变异(valueHasMutated函数被调用或数组有一个元素添加或删除)突然按钮停止按钮并变成简单文本,它们也不起作用,因为他们停止调用他们绑定的函数.从代码片段中可以看出,单击绑定是通过标记完成的,并且不能按预期工作.

值得注意的是,我正在调用该valueHasMutated函数,否则视图不会更新购物车中的商品数量.

为了说明这里的问题是一些图像:

在按下按钮之前

在按下按钮之前

按下按钮后

按下按钮后

我不太明白为什么会发生这种情况,我猜它与Kendo UI有关,而不是与knockout.js有关.

我也做了一个小提示来证明这个问题,你可以在这里找到它

use*_*914 2

正如本文指出的,Kendo 和 Knockout 集成并不完全支持(http://www.telerik.com/blogs/knockout-js-and-kendo-ui---a-pot-duo),因此在某些情况下必须做一些解决方案。

首先尝试使用 Knockout 模板:

<script type="text/html" id="cartListTemplate">
  <div class="km-listview-link cart-item-container" data-id="text: Id">
    <div class="product-image">
      <img data-bind="attr:{src: ImageUrl}">
    </div>
    <div class="product-description">
      <p data-bind="text: Name"></p>
      <p data-bind="text: formattedPrice"></p>
      <p data-bind="text: quantity"></p>
    </div>
    <button data-icon="delete" class="km-big" data-bind="kendoMobileButton: $root.removeItem">Delete</button>
  </div>
</script>
Run Code Online (Sandbox Code Playgroud)

请注意,“a”标签已更改为简单的按钮标签,将其绑定到kendo移动按钮(https://rniemeyer.github.io/knockout-kendo/web/Button.html)。然后必须通知视图使用 Knockout 模板而不是 Kendo 模板:

<div data-role="view" id="cart" data-title="Cart" data-layout="main-layout">
  <div data-bind="if: items().length == 0">No items currently in cart</div>
  <ul data-role="listview" data-style="inset" data-bind="kendoListView: { data: items, template: 'cartListTemplate', useKOTemplates: true }"></ul>
</div>
Run Code Online (Sandbox Code Playgroud)

最后,为了使删除功能正常工作,将其绑定到视图模型并接收当前项目作为参数:

self.removeItem = function(item) {
    if (item.quantity > 1) {
      var cartItem = self.items().filter(function(element) {
        return element.Id == item.Id;
      })[0];
      cartItem.quantity--;
      self.items.valueHasMutated();
    } else {
      self.items.remove(item);
    }
    app.saveCart();
  }.bind(self);
Run Code Online (Sandbox Code Playgroud)

唯一需要注意的是,该值已发生突变,会进行视图刷新,这有时会与 Kendo 小部件混淆,因此 kendo 淘汰库使用普通标签来指定数据绑定属性中的角色。这是因为目前淘汰赛剑道库不支持数据角色初始化,而是使用数据绑定初始化。

请在以下位置找到工作示例:https://jsfiddle.net/aveze/Lykducos/