I hava a viewmodel as follow :
define(
['jquery', 'knockout', 'knockout.mapping', 'data/data', 'models/models'],
function ($, ko, mapping, data, models) {
var post = {},
getPost = function (param) {
$.when(data.deferredRequest('postDetail', param.id))
.done(function (result) {
mapping.fromJS(result, {}, post);
console.log(result.title === post.title()); // ---> this is true
console.log(ko.isObservable(post.title)); // ---> this is true
});
};
return {
post : post,
getPost: getPost
};
});
I want to show title property in the html as follow :
<section id="section-post-detail" class="view" >
<div class="page-header">
<h3 data-bind="text: post.title"></h3> <!-- show nothing -->
<h3 data-bind="text: post().title"></h3> <!-- error -->
<h3 data-bind="text: post.title()"></h3> <!-- error -->
</div>
</section>
I tried three ways to show title property, however all those are failed. Did I miss anything?
Edited
I tweaked source code as follow. I added title property on viewmodel and updated it inside the getPost and then I succesfully accessed the title property of the viewmodel, not title property on post model.
define(
['jquery', 'knockout', 'knockout.mapping', 'data/data', 'models/models'],
function ($, ko, mapping, data, models) {
var post = {},
title = ko.observable(''),
getPost = function (param) {
$.when(data.deferredRequest('postDetail', param.id))
.done(function (result) {
mapping.fromJS(result, {}, post);
title(post.title());
console.log(result.title === post.title()); // ---> this is true
console.log(ko.isObservable(post.title)); // ---> this is true
});
};
return {
post : post,
title : title,
getPost: getPost
};
});
<section id="section-post-detail" class="view" >
<div class="page-header">
<h3 data-bind="text: title"></h3>
</div>
</section>
However, as you see data-bind="text: title" is not the title propery on post, but the title property on viewmodel. This is not what I want. I would like to acces title property on post object.
Please correct my approacth.
I think the problem is that you are initially creating your viewmodel as an empty object, like this:
And then you are trying to update the viewmodel, like this:
However, the documentation for the mapping plugin at http://knockoutjs.com/documentation/plugins-mapping.html seems to indicate that you should create the viewmodel like this:
Then, when you need to call the server to get updated data, you can do this:
The important thing to consider, which I think RP was driving at, is that you can't create the viewmodel until after you have the data.
Not sure when that you are applying bindings, but it appears that at the time of binding, you are just binding against the empty object. Then, when your AJAX request finishes, it adds the observables, but since
post
itself isn't observable, the UI does not update.You could consider calling applyBindings after your request finishes like:
Then bind against it like: