按下以下代码中的按钮可以做两件事:它在嵌套视图模型中执行一个函数,并在父视图模型中执行computed
。
var MasterViewModel = function () {
var self = this;
self.nested = new FirstViewModel();
self.func = ko.computed (function() {
var items = self.nested.array();
alert("executed");
});
}
var FirstViewModel = function () {
var self = this;
self.array = ko.observableArray([]);
self.push = function () {
self.array.push(new SecondViewModel());
alert("pushed");
}
}
var SecondViewModel = function () {
var self = this;
self.z = ko.observable();
}
var mvm = new MasterViewModel();
ko.applyBindings(mvm);

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="with: nested">
<button data-bind="text: 'push me', click: push"></button>
</div>
&#13;
但是,如果将computed
更改为一个简单的函数,则在按下按钮时它不会执行。为什么呢?
var MasterViewModel = function () {
var self = this;
self.nested = new FirstViewModel();
self.func = function() {
var items = self.nested.array();
alert("executed");
};
}
var FirstViewModel = function () {
var self = this;
self.array = ko.observableArray([]);
self.push = function () {
self.array.push(new SecondViewModel());
alert("pushed");
}
}
var SecondViewModel = function () {
var self = this;
self.z = ko.observable();
}
var mvm = new MasterViewModel();
ko.applyBindings(mvm);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="with: nested">
<button data-bind="text: 'push me', click: push"></button>
</div>
&#13;
答案 0 :(得分:1)
作为已接受答案的补充,我在此处张贴documentation的相关部分:
依赖关系跟踪如何运作
[...]
它实际上非常简单而且非常可爱。跟踪算法 是这样的:
- 每当你声明一个计算的observable时,KO立即调用它的赋值函数来获得它的初始值。
- 当评估程序函数正在运行时,KO设置对任何可观察对象(包括其他计算的可观察对象)的订阅 评估员读。订阅回调设置为导致 评估器再次运行,将整个过程循环回到步骤1 (处理任何不再适用的旧订阅)。
- KO通知任何订阅者有关您计算的observable的新值。
醇>
如果您想阻止依赖项创建,请使用peek
:
Knockout的自动依赖性跟踪通常会做到这一点 你要。但有时您可能需要控制哪些可观察量 将更新您的计算的observable,尤其是如果计算的 observable执行某种操作,例如创建Ajax 请求。
peek
函数允许您访问可观察或计算 可以观察而不创建依赖。
所以给定的代码将改为:
var MasterViewModel = function () {
var self = this;
self.nested = new FirstViewModel();
self.func = ko.computed (function() {
var items = self.nested.array.peek();
alert("executed");
});
}
var FirstViewModel = function () {
var self = this;
self.array = ko.observableArray([]);
self.push = function () {
self.array.push(new SecondViewModel());
alert("pushed");
}
}
var SecondViewModel = function () {
var self = this;
self.z = ko.observable();
}
var mvm = new MasterViewModel();
ko.applyBindings(mvm);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="value: func">
<div data-bind="with: nested">
<button data-bind="text: 'push me', click: push"></button>
</div>
</div>
&#13;
请注意,现在,按下按钮时,仅显示"pushed"
的警告。
答案 1 :(得分:0)
首先:<div data-bind="func">
中的bindingName: boundValue
为我举起了一面红旗。通常,绑定的格式为self.array
。
但是回答这个问题:只要计算出任何可观察到的可观察量,就会重新计算计算值。您正在更改FirstViewModel#push
中的MasterViewModel
,因此自然会重新计算在self.nested.array
中使用它的计算值(作为NSDate *startDate = [NSDate date];
NSDate *endDate = [startDate dateByAddingTimeInterval:+7*24*60*60];
NSDateFormatter *df=[[NSDateFormatter alloc] init];
[df setDateFormat:@"yyyy-MM-dd hh:mm a"];
- (BOOL)validateDates:(NSDate*)startDate EndDate:(NSDate*)endDate{
NSComparisonResult dateCompareResutFinal = [startDate compare:endDate];
if (dateCompareResutFinal == NSOrderedDescending) {
[RKDropdownAlert dismissAllAlert];
[RKDropdownAlert title:AlertNotificationError message:@"Start date should be less than End date" backgroundColor:[UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.7] textColor:[UIColor whiteColor] time:2 delegate:self]
;
return NO;
}else if (dateCompareResutFinal == NSOrderedSame) {
[RKDropdownAlert dismissAllAlert];
[RKDropdownAlert title:AlertNotificationError message:@"Both dates cannot be same" backgroundColor:[UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.7] textColor:[UIColor whiteColor] time:2 delegate:self];
return NO;
}else{
return YES;
}
}
)。