Javascript 如何将具有子可观测值的函数绑定到可观测数组?

Javascript 如何将具有子可观测值的函数绑定到可观测数组?,javascript,knockout.js,Javascript,Knockout.js,我有以下视图模型: var Order = function(data) { this.fruits = ko.observableArray(ko.utils.arrayMap(data.Fruis, function(item) { return item; })); this.vegetables = ko.observableArray(ko.utils.arrayMap(data.Vegetables, function(item) { return item; })); }

我有以下视图模型:

var Order =  function(data) {
  this.fruits = ko.observableArray(ko.utils.arrayMap(data.Fruis, function(item) { return item; }));
  this.vegetables = ko.observableArray(ko.utils.arrayMap(data.Vegetables, function(item) { return item; }));
};
我需要定义一些绑定到特定实例的子属性和子观测值,以及一些水果和蔬菜的常用方法:

var Items =  function(data, type) {
  var self = this;
  self.type = type;
  self.choice = ko.observable(-1);
  self.choice.select = ko.computed(function(){
    var id = self.choice();
    // do stuff
  });
  self.choice.remove = function() {
    var id = self.choice.peek();
    // do stuff
  };
  self.add = function(code) {
    //do stuff
    self.choice(id);
  };
};
这是绑定包含我的方法集和子观测值的函数的正确方法,以便我可以使用以下方法:

orderViewModel.fruits.add("apples");
orderViewModel.fruits.add("bananas");
orderViewModel.fruits.choice(0);
orderViewModel.fruits.choice.remove();

console.log(ko.tpJSON(orderViewModel));
// prints: {fruits: [bananas], vegetables: []};
我认为没有必要使用扩展器,因为属性和方法不是通用的,也不需要对所有可观察对象通用


我试着从我的Item函数返回一个可观察数组,但是我无法让它工作,因为子属性和子可观察值已经丢失。如何将
绑定到我的可观察数组?

即使您可能不想创建扩展器,您在这里所做的是扩展可观察数组

如果不想注册扩展器,可以创建一个小的helper函数来创建
observableArray
,并在返回之前向其添加一些方法和属性

在下面的示例中,您可以看到一些示例代码。一些重要的建议:

  • 如果使用这种方法,我建议不要覆盖
    observableArray
    中的默认方法。例如:
    remove
    默认取一个项目;您希望它与外部
    选项
    索引一起工作。。。最好选择一个不同的名字,这样你就可以同时支持这两个名字
  • 如果您经常使用扩展,那么创建一个干净的viewmodel来存储可观察数组是值得的。可以定义导出到普通数组的
    toArray
    方法
var obscolection=函数(initialItems){
var项目=可观察到的ko(初始项目);
items.choice=ko.可观察(-1);
items.add=items.push;
var ogRemove=items.remove.bind(items);
//我会把它重命名为“deleteChoice”
items.remove=函数(){
var index=items.choice();
ogRemove(items()[索引]);
//在这里将选项重置为-1?
};
退货项目;
};
var fruits=obsCollection([“苹果]);
原木(水果);
水果。添加(“香蕉”);
水果。选择(0);
水果。去掉();
原木(水果);
水果。去掉();
水果。添加(“芒果”);
水果。添加(“柠檬”);
原木(水果);
功能日志(d){
log(JSON.stringify(ko.unwrap(d));
}

THX,用
删除调整了错误,所以现在是
选择。删除
你能更新你的答案吗?我马上就要得到答案了,我相信内部方法,
项目应该是
这个
我不确定你的意思。。。扩展时,跟踪
上下文非常重要,但如果在
obsCollection
的闭包中定义了所有方法,则只需在
中引用可观察数组实例即可。请注意,您可以使用
bind
来修复
。如果您希望
类型
暴露在外部,我会将其放入
项目
(因为这是您返回的内容)。然后,您可以通过
项引用它。键入
,无需使用
。如果
type
是一个“private”变量,则可以将其作为参数传递,从而使其在
items
的闭包中可用。您不能使用
var self=this
,因为我们没有使用
new
关键字,当我们进入
obscolection
时,
this
上下文可以是任何内容,具体取决于调用方的上下文。您的回答对我帮助很大!我接受你的答案,因为它能引导我找到一个有效的解决方案,我不能多次投票,但我认为它并没有完全解决可观察对象的自定义方法中
this
的用法。。