1

I'm using Knockout's foreach binding to generate a list of inventory items with a quantity input field. When the user changes the quantity I want to post the new value to the server.

I've come up with a solution, but I'm interested in feedback as to whether I'm using best knockout practices.

I'm using two view models. One represents the inventory and is just an observable array of individual inventory line items:

var inventory = function(lineItems) {
    var self = this;
    self.items = ko.observableArray(lineItems);
};

The second represents an inventory line item:

var lineItem = function(id, text, quantity, quantityChangedCallback) {
    var self = this;
    self.id = ko.observable(id);
    self.itemName = ko.observable(text);
    self.quantity = ko.observable(quantity);

    self.quantity.subscribe(function() {
        quantityChangedCallback(self);
    });
};

HTML is:

<ul data-bind="foreach: items">
    <li>
        <span data-bind="text: itemName"></span>:&nbsp;
        <input class="invLineItem" data-bind="value: quantity"/>
    </li>
</ul>

The rest of my javascript:

var lineItemArray = [
    new lineItem(1, 'Item 01', 0, onQuantityChanged),
    new lineItem(2, 'Item 02', 0, onQuantityChanged),
    new lineItem(3, 'Item 03', 2, onQuantityChanged)
    ];

ko.applyBindings(new inventory(lineItemArray));

function onQuantityChanged(item) {
    alert("Post change to server: " + ko.toJSON(item));
} 

My questions are,

1) Is my use of subscribe a good practice for getting notified when a quantity changes? It seems to work great and only gets called when the corresponding quantity input element's focus is lost and its value changed. This is exactly what I want.

2) What about the callback approach? This is the part that doesn't feel quite right, but it was the cleanest way I could come up with to get back out of an item's view model in order to apply additional logic and do the post.

I have a fiddle here: http://jsfiddle.net/kenswdev/YHHSu/7/

Thanks in advance for any suggestions!

4

1 回答 1

1

这做得很好。针对您的问题:

1) 是的,这是一个完美的订阅用例。

2) 您可以考虑创建一个构造函数来封装您想要从订单项中获得的行为,而不是外部回调。例如:

function LineItem(id, text, quantity, quantityChangedCallback) {
    var self = this;
    self.id = ko.observable(id);
    self.itemName = ko.observable(text);
    self.quantity = ko.observable(quantity);

    self.quantity.subscribe(function() {
      self.onChange();
    });
};

LineItem.prototype = {
  onChange: function() {
    alert("Post change to server: " + ko.toJSON(this));
  }
};

您是否考虑过使用下划线的 debounce() 之类的方法来消除 ajax 调用的抖动?这可能有助于防止一个非常健谈的 API 接口:

于 2013-01-03T00:23:28.530 回答