Knockout.js - 尝试将 JSON 添加到视图模型未定义
Knockout.js - Trying to add JSON to viewmodel is undefined
我已经看到了几个与此相关的问题,但我仍然无法弄清楚我在这里做错了什么。
我想做的是获取一个从服务器返回的 JSON 对象,它看起来像这样:
{
"firstname": "Blanchard",
"lastname": "Buckner",
...
}
视图模型执行 AJAX 调用,数据似乎设置正确。但是当我尝试将它传递到我的 singleContact 函数以绑定到视图时,没有任何反应。
我是 Knockout 的新手,所以我确定我犯了一个很容易犯的错误,但我已经尝试了一段时间来解决这个问题,但没有任何效果。
// Binds json db data to each contact.
function singleContact(data) {
var self = this;
self.firstName = data.firstname;
self.lastName = data.lastname;
self.fullName = ko.computed(function() {
return self.firstName + " " + self.lastName;
}, self);
self.image = data.image;
self.position = data.position;
self.company = data.company;
};
function detailViewModel(contactID) {
var self = this;
self.contactID = ko.observable(contactID);
self.contact = ko.observableArray([]);
self.getContact = function(id) {
$.ajax({
type: 'GET',
url: 'http://localhost:3000/contacts/' + id,
dataType: 'json',
success: function(data) {
console.log(singleContact(data)); <---- Always Undefined. The data is a JSON object.
}
});
}
self.getContact(self.contactID());
};
编辑:
这是标记,第一次应该包含它。
<!-- ko foreach: contact -->
<img class="contact__image" data-bind="attr:{src: image, alt: fullName}" />
<h1 data-bind="text: fullName"></h1>
<h2>
<span data-bind="text: position"></span>,
<span data-bind="text: company"></span>
</h2>
<h5>Notes on <span data-bind="text: fullName"></span></h5>
<p></p>
<!-- /ko -->
您需要使用 new
关键字来创建一个 singleContact 对象:
var contact = new singleContact(data);
然后可以将其分配给 detailViewModel 上的可观察对象:
self.singlecontact(contact);
我还建议您对 viewModel 使用 Upper Camelcase。 IE。 DetailViewModel
而不是 detailViewModel
,就像在使用面向对象编程时使用任何其他语言一样。
这是一个工作示例。缺少的是您没有将创建的模型推入 observableArray。我已经展示了您可以取回一组结果并轻松将其推送。
function DetailViewModel(id) {
var self = this;
self.contacts = ko.observableArray([]);
// make ajax call.. mocking here
var results = ajax();
results.forEach(function(result) {
self.contacts.push(new Contact(result));
});
}
function Contact(data) {
var self = this;
self.firstName = data.firstName;
self.lastName = data.lastName;
self.company = data.company;
self.position = data.position;
self.image = data.image;
self.fullName = ko.pureComputed(function() {
return self.firstName + ' ' + self.lastName;
});
return self;
}
function ajax() {
return [{
firstName: 'Rich',
lastName: 'Hickey',
company: 'Cognitect',
position: 'CTO',
image: 'http://gotocon.com/dl/photos/speakers/Rich%20Hickey2.jpg'
}, {
firstName: 'Scott',
lastName: 'Hanselman',
company: 'Microsoft',
position: 'Architect',
image: 'http://www.globalnerdy.com/wordpress/wp-content/uploads/2009/09/scott_hanselman.jpg'
}];
}
$(function() {
ko.applyBindings(new DetailViewModel());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<!-- ko foreach: contacts -->
<div>
<img class="contact__image" data-bind="attr:{src: image, alt: fullName}" style="width: 100px; height: 150px" />
<h1 data-bind="text: fullName"></h1>
<h2>
<span data-bind="text: position"></span>,
<span data-bind="text: company"></span>
</h2>
<h5>Notes on <span data-bind="text: fullName"></span></h5>
</div>
<!-- /ko -->
我已经看到了几个与此相关的问题,但我仍然无法弄清楚我在这里做错了什么。
我想做的是获取一个从服务器返回的 JSON 对象,它看起来像这样:
{
"firstname": "Blanchard",
"lastname": "Buckner",
...
}
视图模型执行 AJAX 调用,数据似乎设置正确。但是当我尝试将它传递到我的 singleContact 函数以绑定到视图时,没有任何反应。
我是 Knockout 的新手,所以我确定我犯了一个很容易犯的错误,但我已经尝试了一段时间来解决这个问题,但没有任何效果。
// Binds json db data to each contact.
function singleContact(data) {
var self = this;
self.firstName = data.firstname;
self.lastName = data.lastname;
self.fullName = ko.computed(function() {
return self.firstName + " " + self.lastName;
}, self);
self.image = data.image;
self.position = data.position;
self.company = data.company;
};
function detailViewModel(contactID) {
var self = this;
self.contactID = ko.observable(contactID);
self.contact = ko.observableArray([]);
self.getContact = function(id) {
$.ajax({
type: 'GET',
url: 'http://localhost:3000/contacts/' + id,
dataType: 'json',
success: function(data) {
console.log(singleContact(data)); <---- Always Undefined. The data is a JSON object.
}
});
}
self.getContact(self.contactID());
};
编辑: 这是标记,第一次应该包含它。
<!-- ko foreach: contact -->
<img class="contact__image" data-bind="attr:{src: image, alt: fullName}" />
<h1 data-bind="text: fullName"></h1>
<h2>
<span data-bind="text: position"></span>,
<span data-bind="text: company"></span>
</h2>
<h5>Notes on <span data-bind="text: fullName"></span></h5>
<p></p>
<!-- /ko -->
您需要使用 new
关键字来创建一个 singleContact 对象:
var contact = new singleContact(data);
然后可以将其分配给 detailViewModel 上的可观察对象:
self.singlecontact(contact);
我还建议您对 viewModel 使用 Upper Camelcase。 IE。 DetailViewModel
而不是 detailViewModel
,就像在使用面向对象编程时使用任何其他语言一样。
这是一个工作示例。缺少的是您没有将创建的模型推入 observableArray。我已经展示了您可以取回一组结果并轻松将其推送。
function DetailViewModel(id) {
var self = this;
self.contacts = ko.observableArray([]);
// make ajax call.. mocking here
var results = ajax();
results.forEach(function(result) {
self.contacts.push(new Contact(result));
});
}
function Contact(data) {
var self = this;
self.firstName = data.firstName;
self.lastName = data.lastName;
self.company = data.company;
self.position = data.position;
self.image = data.image;
self.fullName = ko.pureComputed(function() {
return self.firstName + ' ' + self.lastName;
});
return self;
}
function ajax() {
return [{
firstName: 'Rich',
lastName: 'Hickey',
company: 'Cognitect',
position: 'CTO',
image: 'http://gotocon.com/dl/photos/speakers/Rich%20Hickey2.jpg'
}, {
firstName: 'Scott',
lastName: 'Hanselman',
company: 'Microsoft',
position: 'Architect',
image: 'http://www.globalnerdy.com/wordpress/wp-content/uploads/2009/09/scott_hanselman.jpg'
}];
}
$(function() {
ko.applyBindings(new DetailViewModel());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<!-- ko foreach: contacts -->
<div>
<img class="contact__image" data-bind="attr:{src: image, alt: fullName}" style="width: 100px; height: 150px" />
<h1 data-bind="text: fullName"></h1>
<h2>
<span data-bind="text: position"></span>,
<span data-bind="text: company"></span>
</h2>
<h5>Notes on <span data-bind="text: fullName"></span></h5>
</div>
<!-- /ko -->