更新viewmodel时,视图中的表格单元格不会更新

时间:2016-12-21 14:52:33

标签: knockout.js

当我更新js / knockout代码中的viewmodel时,我无法弄清楚为什么视图中的表格单元格没有更新。

这是我的fiddle我在@ haim770和@Matt.kaaj的帮助下工作。所以当你跳出最后一行的最后一个单元格时。然后在新行的第一个单元格中输入内容并标签,并且应该更新描述。我在控制台中检查了它是否正确更新了viewmodel。当谷歌搜索它时,我发现我必须使我的可观察数组中包含可观察数据。所以我认为我正在使用映射插件正确地做到这一点。 这是我的小提琴代码。

HTML:

<table class="table table-bordered table-striped" id="brochureItems">
<thead>
    <tr>
        <th>
            Item No.
        </th>
        <th>
            Broc Code
        </th>
        <th width="40%">
            Item Desc
        </th>
        <th>
            Retail
        </th>
        <th>
            Remove
        </th>
    </tr>
</thead>
<tbody data-bind="foreach: items">
    <tr>
        <td>
            <input data-bind="value: itemNo, hasFocus: true, event: { blur: $parent.checkItemNo }" class="form-control item-ID" />
        </td>
        <td>
            <div data-bind="if: ($index() < ($parent.items().length - 1))"><input data-bind="value: brocCode" class="form-control" readonly="readonly" /></div>
            <div data-bind="if: ($index() === ($parent.items().length - 1))"><input data-bind="value: brocCode" class="form-control" /></div>

        </td>
        <td class="item-desc">
            <input data-bind="value: itemDesc" class="form-control" tabindex="-1" />
        </td>
        <td class="item-retail">
            <div data-bind="if: ($index() === ($parent.items().length - 1))"><input data-bind="value: retail, valueUpdate: 'afterkeydown', enterPress: 'addRow'" class="form-control" /></div>
            <div data-bind="if: ($index() < ($parent.items().length - 1))"><input data-bind="value: retail, valueUpdate: 'afterkeydown'" class="form-control" /></div>
        </td>
        <td class="remove"><span class="glyphicon glyphicon-remove removeRow" data-bind="click: $parent.removeItem"></span></td>

    </tr>
</tbody>

JS /敲除:

    var itemsModel = function(items) {
    var self = this;
  //console.log(JSON.stringify(items));
  //self.items = ko.observableArray();
  //ko.mapping.fromJS(items,{},self.items)
  //self.items = ko.mapping.fromJSON(items);
  //self.items = ko.observableArray(items);

  self.items = ko.mapping.fromJSON(items);

  self.checkItemNo = function(data) {
    console.log("blurred!");
    //data = ko.observable(data);
    //itemModel(data.itemNo)
    //var itemNo = $.trim(data.itemNo);
    var itemNo = "abc";
    if (itemNo != "") {
      var item = "";
        /*
        $.each(fullItemList, function(i, v) {
        if (v.No.search(itemNo) != -1) {
        item = v.Description;
        return;
        }
        });
        if(item != "") {
        console.log("found: " + item);
        var match = ko.utils.arrayFirst(self.items, function(item) {
        return itemNo === item.itemNo;
        });
        */
      var match = false;
      item = "Mudguard front";
      if (!match) {
        console.log("not a match!");
        console.log(data);
        data.itemDesc = item;
      }
    }
  }

  self.addLine = function() {
    self.items.push(
      {
        itemNo: "",
        brocCode: "",
        itemDesc: "",
        retail: ""
      }
    )
  };

  self.removeItem = function(item) {
    self.items.remove(item);
  };
};

ko.bindingHandlers.enterPress = {
  init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    var allBindings = allBindingsAccessor();
    element.addEventListener('keydown', function (event) {
      var keyCode = (event.which ? event.which : event.keyCode);
      if (keyCode === 13 || (!event.shiftKey && keyCode === 9)) {
        event.preventDefault();
        console.log("hit enter/tab!");
        bindingContext.$root.addLine();
        return false;
      }
      return true;
    });
  }
};

function GetItems() {
            //var itemsJSON = @Html.Raw(Json.Encode(Model.brochureItems));
            var itemsJSON =  '[{"brochureId":1,"itemNo":"1000","brocCode":"1000","itemDesc":"Bicycle","retail":13.5},{"brochureId":1,"itemNo":"1100","brocCode":"1100","itemDesc":"Front Wheel","retail":35},{"brochureId":1,"itemNo":"1120","brocCode":"1120","itemDesc":"Spokes","retail":12.5},{"brochureId":1,"itemNo":"1150","brocCode":"1150","itemDesc":"Front Hub","retail":5},{"brochureId":1,"itemNo":"1151","brocCode":"1151","itemDesc":"Axle Front Wheel","retail":14},{"brochureId":1,"itemNo":"120","brocCode":"120","itemDesc":"Loudspeaker, Black, 120W","retail":12.5},{"brochureId":1,"itemNo":"125","brocCode":"125","itemDesc":"Socket Back","retail":10}]';
            var viewModel = new itemsModel(itemsJSON);
            ko.applyBindings(viewModel);
        }

$(document).ready(function () {
    GetItems();
});

更新

更新了代码,这里是新的fiddle

1 个答案:

答案 0 :(得分:1)

mapping plugin为您完成工作,并为正在发送的数据创建可观察变量。添加新行后,您需要有一个子视图模型,并添加一个本身包含可观察变量的VM的新实例。

var itemsModel = function(items) {
    var self = this;
  //console.log(JSON.stringify(items));
  //self.items = ko.observableArray();
  //ko.mapping.fromJS(items,{},self.items)
  //self.items = ko.mapping.fromJSON(items);
  //self.items = ko.observableArray(items);

  self.items = ko.mapping.fromJSON(items);

  self.checkItemNo = function(data) {
    console.log("blurred!");
    //data = ko.observable(data);
    //itemModel(data.itemNo)
    //var itemNo = $.trim(data.itemNo);
    var itemNo = "abc";
    if (itemNo != "") {
      var item = "";
        /*
        $.each(fullItemList, function(i, v) {
        if (v.No.search(itemNo) != -1) {
        item = v.Description;
        return;
        }
        });
        if(item != "") {
        console.log("found: " + item);
        var match = ko.utils.arrayFirst(self.items, function(item) {
        return itemNo === item.itemNo;
        });
        */
      var match = false;
      item = "Mudguard front";
      if (!match) {
        console.log("not a match!");
        console.log(data);
        data.itemDesc = item;
      }
    }
  }

  self.addLine = function() {
    self.items.push(new RowViewModel() )
  };

  self.removeItem = function(item) {
    self.items.remove(item);
  };
};

var RowViewModel = function(){
  var self = this;
  self.itemNo = ko.observable();
  self.brocCode = ko.observable();
  self.itemDesc = ko.observable();
  self.retail = ko.observable();

}