Reputation: 5565
I don't understand why the top binding does not work, but the statement "with" does work.
I have set up the question on JSFiddle here.
Why does this not appear when it is bound to Info.Title?
<div data-bind="text: Info.Title"></div>
<hr/>
But this does when I use the with statement?
<div data-bind="with: Info">
<div>
<h1 data-bind="text: Title"></h1>
</div>
</div>
Upvotes: 0
Views: 95
Reputation: 2125
The first binding is bound to the Title
property (which is undefined) of the Info
observable. When the ajax call is done, the Info
object is replaced - Info.Title
is no longer the same Info.Title
that was originally bound.
Within the with:
-scope, however, I believe that the bindings in that scope are re-evaluated when the Info
observable is changed, therefore the new Title
is re-bound correctly.
To amend this, you need to not replace Info
, but have its observables updated when the ajax is done. Also, Info
does not need to be an observable itself. Here's an edited fiddle with a suggestion: http://jsfiddle.net/PQkJb/
Upvotes: 1
Reputation: 1690
The problem is that your Info property is undefined when the binding happens initially. I updated to add a method to your VM that checks if Info is populated and then returns the Title. Here's the updated example on JSFiddle. The updated binding code is this, calling the VM function:
<div data-bind="text: GetTitle()"></div>
The updated VM looks like this, note the function added at the end:
function DareDetailViewModel() {
var self = this;
self.Info = ko.observable();
var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
$.getJSON(flickerAPI, {
format: "json"
})
.done(function (data)
{
self.Info(new MapInfo(data));
console.log(data);
});
self.GetTitle = function() {
if(self.Info())
return self.Info().Title();
};
};
Another option is to initialize your Info property with an object that also has an initial Title. But that seems the longer way to do it so I didn't. :)
Upvotes: 1