[Knockout.js] 改變選擇與敲除綁定事件,我怎麼知道它是否是一個真正的變化



Answers

這只是一個猜測,但我認為這是因為level是一個數字。 在這種情況下, value綁定將觸發change事件以使用字符串值更新level 。 您可以通過確保level是一個字符串來解決這個問題。

此外,做這件事的更多“敲除”方式是不使用事件處理程序,而是使用可觀察事件和訂閱。 使level成為可觀察值,然後添加一個訂閱,每次更改時都會運行該訂閱。

Question

我正在構建權限用戶界面,我擁有每個權限旁邊的選擇列表的權限列表。 權限由綁定到選擇列表的可觀察數據對象表示:

<div data-bind="foreach: permissions">
     <div class="permission_row">
          <span data-bind="text: name"></span>
          <select data-bind="value: level, event:{ change: $parent.permissionChanged}">
                   <option value="0"></option>
                   <option value="1">R</option>
                   <option value="2">RW</option>
           </select>
      </div>
 </div>

現在問題是這樣的:當用戶界面第一次填充時,會引發更改事件。 我打電話給我的ajax函數,獲取權限列表,然後為每個權限項目引發事件。 這真的不是我想要的行為。 我希望只有在用戶真正為選擇列表中的權限挑選出新值時才會引發此問題 ,我該怎麼做?




快速和骯髒,利用一個簡單的標誌:

var bindingsApplied = false;

var ViewModel = function() {
    // ...

    this.permissionChanged = function() {
        // ignore, if flag not set
        if (!flag) return;

        // ...
    };
};

ko.applyBindings(new ViewModel());
bindingsApplied = true; // done with the initial population, set flag to true

如果這不起作用,請嘗試將最後一行包裝在setTimeout()中 - 事件是異步的,所以當applyBindings()已經返回時,最後一行仍然是未決的。




如果您正在使用Knockout,請使用可觀察功能敲除的關鍵功能。
使用ko.computed()方法並在該函數內執行並觸發ajax調用。




我使用這個自定義綁定(基於RP Niemeyer的this小提琴,請參閱他對this問題的回答),它確保數字值從字符串轉換為數字(正如Michael Best的解決方案所建議的那樣):

使用Javascript:

ko.bindingHandlers.valueAsNumber = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var observable = valueAccessor(),
            interceptor = ko.computed({
                read: function () {
                    var val = ko.utils.unwrapObservable(observable);
                    return (observable() ? observable().toString() : observable());
                },
                write: function (newValue) {
                    observable(newValue ? parseInt(newValue, 10) : newValue);
                },
                owner: this
            });
        ko.applyBindingsToNode(element, { value: interceptor });
    }
};

HTML示例:

<select data-bind="valueAsNumber: level, event:{ change: $parent.permissionChanged }">
    <option value="0"></option>
    <option value="1">R</option>
    <option value="2">RW</option>
</select>