Javascript 在knockout.js中进行ajax检索后使字段可见
我想知道如何才能在knockout.js中观察到某些字段,这些字段是通过ajax调用获得的,而不必在viewmodel中定义整个对象。这可能吗?以下是我到目前为止的情况:Javascript 在knockout.js中进行ajax检索后使字段可见,javascript,knockout.js,Javascript,Knockout.js,我想知道如何才能在knockout.js中观察到某些字段,这些字段是通过ajax调用获得的,而不必在viewmodel中定义整个对象。这可能吗?以下是我到目前为止的情况: var viewModel = { lines: new ko.observableArray([]) }; function refreshList(ionum) { var data = {}; data['IONum'] = ionum; $.ajax({ url: 'handle
var viewModel = {
lines: new ko.observableArray([])
};
function refreshList(ionum) {
var data = {};
data['IONum'] = ionum;
$.ajax({
url: 'handlers/getlines.ashx',
data: data,
cache: false,
dataType: 'json',
success: function(msg) {
viewModel.lines(msg);
//here is where I am attempting to make the email address field observable
/*for (var i = 0; i < msg.length; i++) {
viewModel.lines()[i].emailAddress = new ko.observable(msg[i].emailAddress);
}*/
//alert(viewModel.lines[0].emailAddress);
//ko.applyBindings(viewModel);
}
});
}
var viewModel={
行:新ko.observableArray([])
};
函数刷新列表(ionum){
变量数据={};
数据['IONum']=IONum;
$.ajax({
url:'handlers/getlines.ashx',
数据:数据,
cache:false,
数据类型:“json”,
成功:功能(msg){
viewModel.lines(msg);
//这里是我试图让email address字段可见的地方
/*对于(变量i=0;i
我解决了这个问题,发现在将对象设置为我的视图之前最好声明对象上的可观察字段,如
for (var i=0;i<msg.lenth;i++){
msg[i].emailAddress=ko.observable(msg[i].emailAddress);
}
viewModel.lines(msg);
for(var i=0;i以下是我将所谓的“视图数据”(服务器派生的JSON值)转换为KO ViewModels的方法:
define "infrastructure/viewModels", [], (viewModels) ->
exports = {}
isDate = (x) ->
typeof x is "string" and
x.startsWith "/Date("
deserializeDate = (dateString) ->
new Date(parseInt(dateString.substr(6)))
isScalar = (x) ->
x is null or
typeof x is "string" or
typeof x is "number" or
typeof x is "boolean"
exports.fromViewData = (viewData) ->
if isDate viewData
return ko.observable deserializeDate viewData
if isScalar viewData
return ko.observable viewData
viewModel = {}
for own key, value of viewData
if key is "id" then continue
viewModel[key] =
if Array.isArray value
ko.observableArray (exports.fromViewData el for el in value)
else
exports.fromViewData value
return viewModel
return exports
示例用法:
require ["infrastructure/viewModels"], (viewModels) ->
$.getJSON "/url/to/data", (viewData) ->
viewModel = viewModels.fromViewData viewData
ko.applyBindings viewModel
当然,如果不使用CoffeeScript,可以通过单击“Try CoffeeScript”将其转换为JavaScript如果您不使用RequireJS,那么只需从我的模块中获取相关函数,而无需将它们包装在define
中。您可以从普通Javascript对象定义视图模型,如Ajax调用返回的:
var viewModel = ko.mapping.fromJS(data);
// Every time data is received from the server:
ko.mapping.updateFromJS(viewModel, data);
我有一个几乎相似的情况,我的对象是Javascript类的实例。这些类的定义没有考虑敲除,我想修改它们以使用可观察的对象
我创建了一个小助手,用于将常规对象转换为可观察对象。您可以指定可观察字段,也可以在对象(原型)中设置它们。(我曾想过自动执行此操作,但我无法确定哪个字段可以安全转换,哪个字段不可以安全转换。)
+我不明白为什么你认为发布咖啡脚本会有帮助?
(function() {
ko.observableObject = function(object, ko_fields) {
ko_fields = ko_fields || object._ko_fields;
if (!ko_fields) {
return object;
}
for (var f_idx = 0; f_idx < ko_fields.length; f_idx++) {
var field_name = ko_fields[f_idx];
if (object[field_name] && object[field_name].__ko_proto__ !== undefined) {
continue;
}
if (object[field_name] instanceof Array) {
var field_array = object[field_name];
for (var a_idx = 0; a_idx < field_array.length; a_idx++) {
field_array[a_idx] = ko.observableObject(field_array[a_idx]);
}
object[field_name] = ko.observableArray(field_array);
} else {
object[field_name] = ko.observable(object[field_name]);
}
}
return object;
};
})();
// With classes. We define the classes without Knockout-observables
// User.subscriptions is an array of Subscription objects
User = function(id, name) {
this.id = id;
this.name = name;
this.subscriptions = [];
};
Subscription = function(type, comment) {
this.type = type;
this.comment = comment;
});
// Create some objects
var jan = new User(74619, "Jan Fabry");
jan.subscriptions.push(new Subscription("Stack Overflow", "The start"));
jan.subscriptions.push(new Subscription("Wordpress Stack Exchange", "Blog knowledge"));
var chris = new User(16891, "Chris Westbrook");
// We would like to convert fields in our objects to observables
// Either define the fields directly:
ko.observableObject(jan, ['id', 'name', 'subscriptions']);
ko.observableObject(chris, ['id', 'name', 'subscriptions']);
// This will only convert the User objects, not the embedded subscriptions
// (since there is no mapping)
// If you define it in the class prototype, it will work for embedded objects too
User.prototype._ko_fields = ['id', 'name', 'subscriptions'];
Subscription.prototype._ko_fields = ['type', 'comment'];
ko.observableObject(jan);
ko.observableObject(chris);
// It also works with objects that are not created from a class, like your Ajax example
var observable = ko.observableObject({'id': 74619, 'name':'Jan'}, ['id', 'name']);