我只是想从ajax请求中提取一些数据。 ajax调用有效 - 我知道数据已被检索。但它只是没有设置ko.computed的值......
function viewModel() {
this.Id = ko.observable("@Model.Identity()");
this.Points = ko.computed({
read: function () {
$.ajax({
url: '/skills/points',
data: { id: this.Id },
type: 'get',
success: function (data) {
return data;
}
});
},
owner: this
});
}
所以像......这样的电话。
<span data-bind="text: Points"></span>
只是不工作。任何人都可以帮我弄清楚我做错了什么吗?
我正在使用以下代码,遵循RPN的建议 - 我根本无法使其正常运行。它不会看控制器,它不会返回数据......它什么都不做。我已经尝试了所有三个例子都没有成功。
<script type="text/javascript">
//an observable that retrieves its value when first bound
ko.onDemandObservable = function (callback, target) {
var _value = ko.observable(); //private observable
var result = ko.computed({
read: function () {
//if it has not been loaded, execute the supplied function
if (!result.loaded()) {
callback.call(target);
}
//always return the current value
return _value();
},
write: function (newValue) {
//indicate that the value is now loaded and set it
result.loaded(true);
_value(newValue);
},
deferEvaluation: true //do not evaluate immediately when created
});
//expose the current state, which can be bound against
result.loaded = ko.observable();
//load it again
result.refresh = function () {
result.loaded(false);
};
return result;
};
$(document).ready(function () {
function User(id, name) {
this.Id = ko.observable(id);
this.Name = ko.observable(name);
}
function viewModel() {
var self = this;
this.User = ko.onDemandObservable(this.Update, this);
this.Update = function () {
return $.ajax({
url: '/home/user/',
data: { id: 1 },
dataType: 'json'
}).pipe(function (data) {
return new User(data.Id, data.Name);
});
};
};
var model = new viewModel();
ko.applyBindings(model);
model.User();
});
</script>
<span data-bind="text: User.Name"></span>
根据更多说明,我已经缩小了一些问题。将callback
定义为viewModel上的函数似乎不起作用(我不确定为什么)但声明内联函数确实会产生......不同的东西。但仍然没有工作。这是一个更新。
<script type="text/javascript">
//an observable that retrieves its value when first bound
ko.onDemandObservable = function (callback, target) {
var _value = ko.observable(); //private observable
var result = ko.computed({
read: function () {
//if it has not been loaded, execute the supplied function
if (!result.loaded()) {
callback.call(target);
}
//always return the current value
return _value();
},
write: function (newValue) {
//indicate that the value is now loaded and set it
result.loaded(true);
_value(newValue);
},
deferEvaluation: true //do not evaluate immediately when created
});
//expose the current state, which can be bound against
result.loaded = ko.observable();
//load it again
result.refresh = function () {
result.loaded(false);
};
return result;
};
$(document).ready(function () {
function User(id, name) {
this.Id = ko.observable(id);
this.Name = ko.observable(name);
}
function viewModel() {
var self = this;
this.User = ko.onDemandObservable(function(){
$.ajax({
url: '/home/user/',
data: { id: 1 },
dataType: 'json',
success: function (data) {
self.User(new User(data.Id, data.Name));
}
});
}, this);
//this.Update = function () {
// $.ajax({
// url: '/home/user/',
// data: { id: 1 },
// dataType: 'json',
// success: function (data) {
// self.User(new User(data.Id, data.Name));
// }
// });
//};
};
var model = new viewModel();
ko.applyBindings(model);
model.User();
});
</script>
然后尝试显示检索到的任何数据仍然失败。
<span data-bind="text: User.Name"></span>
有点突破!如果我将声明性绑定更改为这样..
<span data-bind="with: User">
<span data-bind="text: Id"></span>
<span data-bind="text: Name"></span>
</span>
然后我开始看到结果。我想我快到了那里......
答案 0 :(得分:13)
正如SLaks指出的那样,由于调用是异步调用的,所以你不能这样做,即“read”函数在检索到响应之前返回。我会推荐这样的东西:
function viewModel() {
var self = this;
this.Id = ko.observable("@Model.Identity()");
this.Points = ko.observable(0);
var refreshPoints = function() {
$.ajax({
url: '/skills/points',
data: { id: self.Id() }, // <-- you need () here!
type: 'get',
success: function (data) {
self.Points(data);
}
});
};
// Now subscribe to the ID observable to update the points whenever the
// ID gets changed:
this.Id.subscribe(refreshPoints);
}
答案 1 :(得分:5)
将一个可观察变量绑定到html变量并更新ko.computed字段中的该字段。不要直接将ko.computed字段绑定到html变量。
self.htmlUserName = ko.observable();
self.computedUserName = ko.computed(function () {
$.ajax(
....
success: function (result) {
self.htmlUserName(result);
}
}
答案 2 :(得分:2)
Knockout绑定不支持异步计算。
相反,您应该使用常规属性并将其设置为AJAX请求的结果 您可以通过在依赖属性的更改处理程序中重新发送AJAX请求来使其可观察。
您还可以使用单独的占位符值将加载指示符添加到绑定的UI。