2014-03-18 22 views
1

jsfiddle example。就像標題所說的那樣,我正在嘗試使用rniemeyer淘汰賽排序示例中的計算觀察值。我不斷收到淘汰賽排序與計算observable不工作

write方法需要實現

此錯誤是在開發者控制檯查看。

我在我的ko.computed上實現了一種寫入方法,但它仍然出錯。我做錯了什麼?

HTML和JavaScript下面

<div id="main"> 
    <h3>Tasks</h3> 
    <div class="container" data-bind="sortable: tasks"> 
     <div class="item"> 
      <span data-bind="visible: !$root.isTaskSelected($data)"> 
       <a href="#" data-bind="text: TestName"></a> 
      </span> 
      <span data-bind="visibleAndSelect: $root.isTaskSelected($data)"> 
       <input data-bind="value: name, event: { blur: $root.clearTask }" /> 
      </span> 
     </div> 
    </div> 
</div> 

var Task = function(first,last) { 
    var self = this; 
    self.firstName = ko.observable(first); 
    self.lastName = ko.observable(last); 
    self.TestName = ko.computed({ 
     read: function(){ 
      return self.firstName() + " " + self.lastName(); 
     }, 
     write: function (item) { 
      console.log(item); 
     } 
    }); 

    return self; 
} 

var ViewModel = function() { 
    var self = this; 
    self.testTasks = ko.observableArray([ 
     new Task("test","one"), 
     new Task("test","two"), 
     new Task("test","three") 
     ]); 

    self.tasks = ko.computed({ 
     read: function() { return self.testTasks();}, 
     write: function(item) {console.log(item);} 
    }); 



    self.selectedTask = ko.observable(); 
    self.clearTask = function(data, event) { 
     if (data === self.selectedTask()) { 
      self.selectedTask(null);     
     } 

     if (data.name() === "") { 
      self.tasks.remove(data); 
     } 
    }; 
    self.addTask = function() { 
     var task = new Task("new"); 
     self.selectedTask(task); 
     self.tasks.push(task); 
    }; 

    self.isTaskSelected = function(task) { 
     return task === self.selectedTask(); 
    }; 
}; 

//control visibility, give element focus, and select the contents (in order) 
ko.bindingHandlers.visibleAndSelect = { 
    update: function(element, valueAccessor) { 
     ko.bindingHandlers.visible.update(element, valueAccessor); 
     if (valueAccessor()) { 
      setTimeout(function() { 
       $(element).find("input").focus().select(); 
      }, 0); //new tasks are not in DOM yet 
     } 
    } 
}; 

ko.applyBindings(new ViewModel()); 

回答

2

由於這個插件的非常筆者說:here,您不能使用計算觀察的;可排序的插件取決於實際的可觀察數組。

當你考慮它時,這是有道理的:當你重新排序元素時,插件實際上是在操縱數組的各種索引。

+0

很好找,謝謝! – gh9

0

這是一個「writableComputedArray」,如果你想要兩全其美。如果您從數組中添加/刪除數據,並且隨後重新計算observable將執行相同的添加/刪除操作,則用戶將不會再次收到通知。但是,確保在數組計算和實際添加/刪除之間沒有差異是您的責任。您可以通過在可排序綁定的afterMove事件中進行必要的更改來完成此操作。

ko.writeableComputedArray = function (evaluatorFunction) { 
    // We use this to get notified when the evaluator function recalculates the array. 
    var computed = ko.computed(evaluatorFunction); 

    // This is what gets returned to the caller and they can subscribe to 
    var observableArray = ko.observableArray(computed()); 

    // When the computed changes, make the same changes to the observable array. 
    computed.subscribe(function (newArray) { 
     // Add any new values 
     newArray.forEach(function (value) { 
      var i = observableArray.indexOf(value); 

      if (i == -1) { 
       // It's a new value, push it 
       observableArray.unshift(value); 
      } 
     }); 

     // Remove any old ones. Loop backwards since we're removing items from it. 
     for (var valueIndex = observableArray().length - 1; valueIndex >= 0; valueIndex--) { 
      var value = observableArray()[valueIndex]; 

      var i = newArray.indexOf(value); 

      if (i == -1) { 
       // It's an old value, remove it 
       observableArray.remove(value); 
      } 
     } 
    }); 

    return observableArray; 
};