在每个数组元素上扩展 ko.viewmodel 失败

extending ko.viewmodel on each array element fails

我可以创建一个视图模型,这样一组可点击的 div 和 favorite/nonfavorite 类型的图标可以正常工作。我使用 knockout 绑定 css 样式,它具有适当的背景图像集。 最喜欢的功能是:

function Favorite() {

  var self = this;
  self.isFavorite = ko.observable();
  self.toggleMe = function(ctx) {
    self = ctx;
    var val = self.isFavorite();
    self.isFavorite(!val);
  };
  self.isFavoriteClass = ko.computed(function() {

    if (self.isFavorite() === true)
      return 'favorite';
    else
      return 'notFavorite';
  });
}

HTML:

<div data-bind="css: {favorite: isFavorite()==true, 
                      notFavorite: !isFavorite() }  ,
                      event: {click: toggleMe}" 
                      style="border:solid red;">

</div>

plnkr: http://plnkr.co/edit/LEwQd544rxrzhNyoyO5F?p=preview

不过,我想用ko.viewmodel插件达到同样的效果。 (好吧,我也想用 ko.mapping :-) )ko.viewmodel 插件参考在这里:
http://coderenaissance.github.io/knockout.viewmodel/

扩展使用 ko.viewmodel 创建的视图模型的语法非常简单。这是他们的例子:

options:{ 
    extend:{
        "{root}.users[i]": function(user){
            user.isDeleted = ko.observable(false);
        }
    }
};

viewmodel = ko.viewmodel.fromModel(model,options));

我可以使用 ko.viewmodel 成功地将数据绑定到我的视图模型: plnkr: http://plnkr.co/edit/afr9B8lPe1W3jCTrfH3w?p=preview

但是,当我尝试扩展视图模型时,点击切换行为也存在,但失败并显示以下消息:

Uncaught ReferenceError: Unable to process binding "with: function(){return FavoritesVm }" Message: Unable to process binding "foreach: function (){return favorites() }" Message: Unable to process binding "event: function (){return {click:toggleFavorite()} }" Message: toggleFavorite is not defined

这是我尝试使用的选项对象:

var myOptions = { 
    extend:{
        "{root}.favorites[i]": function(favorite){
            favorite.toggleFavorite = ko.computed(function() {
              debugger; 
                // self = this;
                // var val = self.isFavorite();
                // self.isFavorite(!val);
                // return favorite;
                var val = this.isFavorite();
                this.isFavorite(!val);
                return favorite;
              }, this);
        }
    } 
}; 

plnkr: http://plnkr.co/edit/1gez79Q0kvPlRUYFcOfS?p=preview

N.B.: 在 SO 上有一个与此类似的问题,关于扩展 ko.viewmodel 以在 {root} 上添加 ko.computed()。但是,我想为每个 {root}.favorite[i] 添加一个方法。看 How can I map a field computed using ko.viewmodelhttp://jsfiddle.net/sublimejs/L6Wm3/8/

问题是您直接映射 favorites 数组,而不是 FavoritesVm,因此,您不能指定 {root}.favorites[i],因为您在 favorites 上下文,而不是 FavoritesVm 上下文。 (即该代码试图在 favorites 自身中找到 favorites 属性)

因此,要指定您要修改 favorites 中的每个元素,您只需简单地 sepcify "[i]":

var myOptions = { 
  extend:{"[i]": function(f) {
      f.toggleFavorite = function() {
        f.isFavorite(!f.isFavorite());
      }
    }
  } 
};

注意:除了你为一个简单的任务使用了太多代码之外,你可以简单地切换值,如我的代码所示,即 f.isFavorite(!f.isFavorite());

Click to see the working plunker