Javascript 淘汰计算与订阅、时间问题
刚刚发现,在KnockoutJS中,订阅函数是在依赖计算之前评估的,需要有人能够提交,因为我在文档或论坛中找不到任何关于Knockouts计时的信息 这意味着:如果我有一个这样的模型Javascript 淘汰计算与订阅、时间问题,javascript,knockout.js,Javascript,Knockout.js,刚刚发现,在KnockoutJS中,订阅函数是在依赖计算之前评估的,需要有人能够提交,因为我在文档或论坛中找不到任何关于Knockouts计时的信息 这意味着:如果我有一个这样的模型 var itemModel = function (i) { var self = this; self.Id = ko.observable(i.Id); self.Title = ko.observable(i.Title); self.State = ko.observabl
var itemModel = function (i) {
var self = this;
self.Id = ko.observable(i.Id);
self.Title = ko.observable(i.Title);
self.State = ko.observable(i.State);
};
var appModel = function () {
var self = this;
self.Items = ko.observableArray() // <-- some code initializes an Array of itemModels here
self.indexOfSelectedItem = ko.observable();
self.selectedItem = ko.computed(function () {
if (self.indexOfSelectedItem() === undefined) {
return null;
}
return self.Items()[self.indexOfSelectedItem()];
});
};
appModel.indexOfSelectedItem.subscribe(function () {
// Do something with appModel.selectedItem()
alert(ko.toJSON(appModel.selectedItem()));
}
…在使用新的索引值重新计算计算值之前,将对订阅函数进行求值,因此我将获得对应于上一个选定索引而不是实际选定索引的selectedItem()
两个问题:
- 是这样吗
- 那么,如果一个简单的函数每次调用时都会得到当前选定的项,而ko.computed在任何时候都会得到求值,而所有事情都已经完成了,我不再需要它,那么我为什么要使用ko.computed()
函数AppModel(){
var self=这个;
self.Items=ko.observearray();
self.selectedItem=ko.observable();
self.indexOfSelectedItem=ko.computed({
读:函数(){
var i,
allItems=self.Items(),
selectedItem=self.selectedItem();
对于(i=0;i
Knockout支持存储/处理实际值,而不仅仅是值的索引,因此对视图进行必要的更改可能并不困难。只需将以前写入indexOfSelectedItem
的所有内容直接写入selectedItem
。对selectedItem
的依赖项将继续正常工作
在设计良好的淘汰应用程序中,您很少需要处理数组项的索引。我建议在一切正常后,删除计算机的写入部分
请参阅:为什么不在selectedItem上?因此appModel.selectedItem.subscribe(函数(){
在这种情况下,当selectedItem
发生更改时,将调用您的函数。顺便说一下,您的计算结果中有一个错误:返回self.Items[self.indexOfSelectedItem()];
应该是返回self.Items()[self.indexOfSelectedItem()];
注意额外的()
因为不仅有一个依赖于索引的计算字段,还有更多。我需要一个处理程序,可以更新UI中的很多内容,所有这些计算字段也都已经更新。我现在应该订阅哪一个?我认为计算字段就像一个getter函数,在调用它时会进行计算。事实上有一段时间,这些都会绑定到一个旧的值,所以我认为最好使用简单的getter函数,不是吗?谢谢你关于额外的()的说法是正确的…谢谢,这真是一个伟大而有用的建议(实际上我不知道如何设计一个好的击倒应用程序)。我会这样做。我还需要索引是可写的,因为我将项目绑定到一个jquery ui accordion,其中accordion面板对应于数组索引。因此,如果我单击accordion面板来选择项目,除了设置appModel.indexOfSelectedItem()之外,我没有找到更好的方法来选择它到手风琴中的面板索引(面板不知道KO模型类).有更好的方法吗?我想有。我会试着想出一个更好的方法,等等。关键是要将视图、模型和绑定彼此分开。最干净的方法是将手风琴作为绑定声明的属性。例如,你可以声明意图“此元素应显示为手风琴,当前活动的面板应与所选项目相关联”。由于Knockout不了解手风琴,您可以为此创建自定义绑定,请参见此处:。(免责声明:这是一个例子。其他人已经为jQuery UI小部件创建了更完整的自定义绑定,请看一看。)啊,好吧。出于某种原因,fiddle拒绝在IE中运行。不过,它似乎是特定于JSFIDLE的。Firefox和Chrome工作得很好。这里有一个小小的扩展:它允许您动态绑定accorion选项(例如,“禁用”
)到视图模型。
function AppModel() {
var self = this;
self.Items = ko.observableArray();
self.selectedItem = ko.observable();
self.indexOfSelectedItem = ko.computed({
read: function () {
var i,
allItems = self.Items(),
selectedItem = self.selectedItem();
for (i = 0; i < allItems.length; i++) {
if (allItems[i] === selectedItem) {
return i;
}
}
return -1;
},
write: function (i) {
var allItems = self.Items();
self.selectedItem(allItems[i]);
}
});
}