如何设置一个可观察的属性,而不会为其触发任何订阅?
我有一个场景是页面加载,进行ajax调用以获取一些数据,数据循环,然后将当前选择的项目设置为observable。我希望能够设置这个observable,而不会触发任何订阅,因为第一次设置这个observable被认为是它的初始状态,订阅不应该在初始状态下执行。
function PlanViewModel() {
var self = this;
self.plans = ko.observableArray();
self.selectedItem = ko.observable();
self.getAllPlans = function () {
$.ajax({
url: "/Backoffice/Home/GetAllPlans",
type: "POST",
data: {},
context: this,
success: function (result) {
var planList = this.plans;
// clear the plan list
planList.removeAll();
$.each(result.plans, function () {
var planDetail = new PlanDetail(this, self);
if (this.IsSelected) {
self.selectedItem(planDetail); // how do I set this without the subscriptions firing?
}
planList.push(planDetail);
});
},
error: function (result) {
alert("An error occured getting plans.");
}
});
}
self.selectedItem.subscribe(function (newItem) {
newItem.repositoryUpdateSelectedPlan();
} .bind(self));
}
答案 0 :(得分:4)
您可以像这样重构代码:
function PlanViewModel() {
var self = this;
self.plans = ko.observableArray();
self.getAllPlans = function () {
$.ajax({
// …
success: function (result) {
// …
$.each(result.plans, function () {
var planDetail = new PlanDetail(this, self);
if (this.IsSelected) {
self.selectedItem = ko.observable(planDetail);
}
planList.push(planDetail);
});
if (self.selectedItem === undefined) {
self.selectedItem = ko.observable();
}
self.selectedItem.subscribe(function (newItem) {
newItem.repositoryUpdateSelectedPlan();
}.bind(self));
},
// …
});
}
}
也就是说,只有在达到所需的初始状态后才能启动Knockout 。
答案 1 :(得分:-1)
谢谢,我沿着那条路走下去并进行了一些修改。必须在get go中在模型上定义selectedItem observable,因为它在整个地方用于绑定,但我确实像你建议的那样移动了订阅部分,而且效果很好。
function PlanViewModel() {
var self = this;
var selectedItemSubscription = null;
self.plans = ko.observableArray();
self.selectedItem = ko.observable();
self.getAllPlans = function () {
$.ajax({
url: "/Backoffice/Home/GetAllPlans",
type: "POST",
data: {},
context: this,
success: function (result) {
var planList = this.plans;
// clear the plan list
planList.removeAll();
$.each(result.plans, function () {
var planDetail = new PlanDetail(this, self);
if (this.IsSelected) {
if (selectedItemSubscription != null)
selectedItemSubscription.dispose();
self.selectedItem(planDetail);
}
planList.push(planDetail);
});
selectedItemSubscription = self.selectedItem.subscribe(function (newItem) {
newItem.repositoryUpdateSelectedPlan();
}.bind(self));
},
error: function (result) {
alert("An error occured getting plans.");
}
});
}
}