使用Knockout 2.0和MVC3 Razor表单,当我引入ajax方法时,我无法进行依赖的可观察工作。我已经设置了一组作为计算的一部分的可观察量,当我返回那些可观察量的产品时,我能够设置一个具有正确结果的SPAN标记。但是,当我尝试使用ajax方法来处理那些observable并返回结果时,我会得到不可预测的行为。首先,当INPUT字段更新时,似乎ajax POST没有拾取其中一个observable(var b POST到action方法为0,但最终更新),然后似乎我无法设置即使正确评估结果也是如此。似乎存在可观察量或ajax调用的时间问题。虽然只是在javascript中继续执行计算工作正常,但我的意图是调用ajax方法来处理更复杂的逻辑。我已经从doc.ready()中删除了对ko.applybindings的调用,并且还将SCRIPT方法移到了页面的底部 - 这是我发现使其部分功能化的唯一方法。我的viewModel设置如下:
var viewModel = {
a: ko.observable(0),
b: ko.observable(1),
c: ko.observable(2),
// commented this out, since
// the dependent observable will handle this
// d: ko.observable(0)
};
在我的依赖观察中:
viewModel.d = ko.dependentObservable(function () {
var theResult = 0;
$('.theLabel').css("visibility", "visible");
theResult=viewModel.a() * viewModel.b() * viewModel.c();
// if we return here we get a valid result
return (theResult);
// prefer to call ajax method
// first check to ensure one variable is set
if (viewModel.a() > 0) {
$.ajax("/myCalculation/getResult", {
data: ko.toJSON(viewModel),
type: "post",
context: viewModel,
contentType: "application/json",
success: function (result) {
// can't set visibility here
$('.theLabel').css("visibility", "visible");
// the POST does not pick up some observables, or
// does not the set dependent observable at all
return result;
}
});
}
});
答案 0 :(得分:2)
您设置的功能有点不对。
1。)在进行AJAX调用之前,您将从函数返回。 return语句后的代码永远不会执行。
2.。)即使你省略了第一个return语句,你的AJAX调用也是异步的...这意味着它将在后台执行并立即将控制权返回给外部作用域。由于您没有return语句,因此您将返回undefined。
3。)成功回调中的注释表明您希望return语句一直传播到计算的observable。 THAT return语句仅限于回调,而不是外部observable。返回值将由jQuery使用,并且您的observable将在很久以后返回。
如果您希望observable调用AJAX函数,则需要一个单独的值来存储异步调用的结果。
这是一个简化的例子:
var viewModel = function(){
var $this = this;
$this.a = ko.observable();
$this.b = ko.observable();
$this.results = ko.observable();
//No need to assign this computed observable to a variable
// because the results will be stored in '$this.results'
// we just need this to handle the automatic updates
ko.computed(function(){
var data = {
a: $this.a(),
b: $this.b()
};
$.post("/do/some/stuff", data, function(results){
$this.results(results);
});
});
};