【问题标题】:knockout sortable with computed observable not working可计算可观察的淘汰赛排序不起作用
【发布时间】:2014-04-24 19:49:01
【问题描述】:

jsfiddle example。就像标题说的那样,我正在尝试使用计算出的 observable 以及 rniemeyer 淘汰赛可排序示例。我不断得到

需要实现write方法

此错误可在开发者控制台中查看。

我的 ko.computed 上有一个 write 方法实现,但它仍然出错。我做错了什么?

下面是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());

【问题讨论】:

    标签: javascript jquery jquery-ui knockout.js knockout-sortable


    【解决方案1】:

    正如这个插件的作者所说here,你不能使用计算的observable; sortable 插件依赖于一个实际的可观察数组。

    仔细想想,这是有道理的:当您重新排序元素时,插件实际上是在操纵数组的各种索引。

    【讨论】:

      【解决方案2】:

      如果您想要两全其美,这里有一个“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;
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-18
        • 2013-08-26
        • 1970-01-01
        • 2023-03-20
        • 2017-10-20
        • 2014-11-05
        • 2012-09-08
        • 2012-07-07
        相关资源
        最近更新 更多