我试图让元素的文本根据它是否被选中而有所不同,但我很难弄清楚如何引用父对象来确定哪个对象是地选择。
我尝试解决的问题的简化示例:
function Model(items){
this.items = ko.observableArray(items);
this.selectedItem = ko.observable();
this.dropDownText = function(item){
if(this.selectedItem()===item){
return item.name;
}else{
return item.dropDownText;
}
}
}
function Item(name, price){
this.name=name;
this.price=price;
this.dropDownText=name + ' ($' + price + ')';
this.dropDownTextFunction = function(item){
return item.name + ' ($' + item.price + ')';
}
}
var m = new Model([new Item('hammer', 5), new Item('nail', 0.03), new Item('tooth', 0.6)]);
m.selectedItem(m.items()[1]);
ko.applyBindings(m);

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<select data-bind="options: items(), value: selectedItem, optionsText: 'dropDownText'"></select>
<span data-bind="text: selectedItem().price"></span>
&#13;
价格不应显示在所选元素中,但应该是其他元素。
我尝试过的事情:
答案 0 :(得分:3)
这是一个解决方案,但不是我希望在我的ko应用程序中实现的解决方案。
function Model(items){
var self = this;
self.items = ko.observableArray(items);
self.selectedItem = ko.observable();
self.selectedItem.subscribe(function() {
console.log('Selected');
items.forEach(function(it) {
if (it === self.selectedItem()) {
it.dropDownText(it.name);
} else {
it.dropDownText(it.name + ' ($' + it.price + ')');
}
});
});
return self;
}
function Item(name, price){
this.name=name;
this.price=price;
this.dropDownText= ko.observable(name + ' ($' + price + ')');
}
var m = new Model([new Item('hammer', 5), new Item('nail', 0.03), new Item('tooth', 0.6)]);
m.selectedItem(m.items()[1]);
ko.applyBindings(m);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<select data-bind="options: items(), value: selectedItem, optionsText: 'dropDownText'"></select>
<span data-bind="text: selectedItem().price"></span>
一个完全必要的事情是dropDownText
是可观察的,因此显示的文本可以在更改时更新。原始代码中缺少这个。
我不喜欢的部分是,只要选定的值发生变化,就必须计算整个列表的observable。
另一种方法是修改项目对象和订阅,这使它更清洁:
function Model(items){
var self = this;
self.items = ko.observableArray(items);
self.selectedItem = ko.observable();
self.selectedItem.subscribe(function() {
items.forEach(function(it) {
it.selected(it === self.selectedItem())
});
});
return self;
}
function Item(name, price){
var self = this;
self.name = name;
self.price = price;
self.selected = ko.observable(false);
self.dropDownText = ko.computed(function() {
return this.selected()
? this.name : this.name + ' ($' + this.price + ')';
},self);
return self;
}
但我真正喜欢的是让viewmodel处理项目的整个创建和管理。您可以使用可以像model.addItem(name,price)
或其他类似additems([{name: '', price:1}, ...])
调用的函数创建一个模型。如果你尝试这条路径,你会发现实现视图模型非常简单明了,因为模型可以自行处理它及其所有组件。如果要从其他代码中使用它,也可以在模型中公开cosntructor。
注意:var self=this
模式简化了在模型中的其他功能中使用this
,如计算的observables