我在html绑定到可观察数组
中选择了列表 <select data-bind="options: myData, optionsText: 'Name', value: selectedId"></select>
当我加载页面时,我将值设置为可观察的selectedId
但是当我设置值时,它会立即调用其订阅事件
selectedId.subscribe(function (row) {
// some logic for retrieving data
});
我不希望订阅事件在以编程方式设置值时调用,但只想在用户从列表中选择内容时调用。
有可能吗?无法找到任何好的例子。
UPDATE1
我以这种方式将值设置为我的可观察selectedId
selectedId(ko.utils.arrayFirst(data(), function(item) {
return item.id=== 5;
}));
我认为因为它的触发订阅事件
答案 0 :(得分:1)
如果您在实际订阅之前设置了初始值,那么您不应该获得订阅事件。例如:
function ViewModel() {
var self = this;
self.selectedID = ko.observable();
self.selectedID(10); // this won't fire the event because we haven't subscribed yet
self.selectedID.subscribe(function(value) {
alert("value changed by user");
});
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="number" data-bind="value: selectedID" />
现在,如果你想解决一般情况,那么值可能会在以后以编程方式更改,而你不希望subscribe
触发,那么你可能想要一个可以用来简单跳过的标志处理subscribe
处理程序。类似的东西:
function ViewModel() {
var self = this;
self.selectedID = ko.observable();
self.selectedID(10); // this won't fire the event because we haven't subscribed yet
var _skipNotification = false; // this tells us whether or not we should process subscribe
// putting this logic in a function makes it easier if you have multiple places
// where you need to programmatically set the id.
function setSelectedID(value) {
_skipNotification = true;
self.selectedID(value);
_skipNotification = false;
}
self.selectedID.subscribe(function(value) {
if (!_skipNotification) {
alert("value changed by user");
}
});
self.changeProgrammatically = function() {
setSelectedID(1);
};
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="number" data-bind="value: selectedID" />
<input type="button" data-bind="click: changeProgrammatically" value="change programmatically" />
这是你的fiddle修复使用上述技术。局部变量_skipNotification
在视图模型中定义,并在subscribe事件中进行检查。然后,从鼠标单击调用的importData
函数如下所示:
this.importData = function () {
skipNotification = true;
self.selectedGroup(ko.utils.arrayFirst(self.availableGroups(), function (val) {
//debugger;
return val.GroupId == 8;
}));
skipNotification = false;
console.log("Lets see if it hits me first");
};
这将设置selectedGroup
而不会导致selectedGroup.subscribe
的正文执行。请注意,因此selectedGroupId
未设置,因此尽管在下拉列表中选择了某些内容,但您的一个范围仍会显示You have chosen Nothing
。我不确定这是不是你真正想要的,但它似乎很有误导性。特别是因为现在让它正确阅读You have chosen Football Team
的唯一方法是首先选择其他内容,然后重新选择Football Team
。