Reputation: 1257
I'm having a list, displaying photo-thumbs When clicking a thumb, a bootstrap modal is opened, displaying the clicked thumb as a fullscreen image. This is done by updating an observable().
problem is.. UI's not updating, resulting in no data displayed, no image or text. Modal popup functionality is working properly.
BUT.. when console.logging the observable. It displays the object as it should, and is updated.
So why does this seem fine when i'm console.logging it, and not in the UI ?
Click event (inside foreach)
<a data-toggle="modal" data-target="#full-modal-photopage" data-bind="click: $parent.setSelectedPhoto">
<img data-bind="attr:{src: BlobUrlPhotoThumb}" style="max-width: 100%; max-height: 100%;" />
</a>
Modal to display selected photo (bootstrap modal)
<div class="modal fade" id="full-modal-photopage" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="z-index: 999999999999">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 id="myModalLabel" data-bind="text: selectedPhoto.PhotoText "></h4>
</div>
<div class="modal-body">
<img data-bind="attr: { src: selectedPhoto.BlobUrlPhoto }" id="full-modal-img" alt="" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
Observable init & setSelectedPhoto script
self.selectedPhoto = ko.observable();
self.setSelectedPhoto = function(selPhoto) {
self.selectedPhoto(selPhoto);
console.log(self.selectedPhoto());
}
Upvotes: 1
Views: 914
Reputation: 338208
Observables are functions. You can use them directly as event handlers in knockout, an extra setSelectedPhoto()
method is superfluous:
<a data-bind="click: $parent.selectedPhoto" data-toggle="modal" data-target="#full-modal-photopage">
<img data-bind="attr:{ src: BlobUrlPhotoThumb}" style="max-width: 100%; max-height: 100%;" />
</a>
Now selectedPhoto
will be updated on click.
In your modal you can use with: selectedPhoto
to a) rebuild the inner part when selectedPhoto
changes and b) set a context for the properties you are referring to:
<div class="modal fade" id="full-modal-photopage" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="z-index: 999999999999">
<div class="modal-dialog">
<div class="modal-content" data-bind="with: selectedPhoto">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 id="myModalLabel" data-bind="text: PhotoText"></h4>
</div>
<div class="modal-body">
<img data-bind="attr: { src: BlobUrlPhoto }" id="full-modal-img" alt="" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
With this kind of setup it's not relevant whether BlobUrlPhoto
or PhotoText
are themselves observables or not. The with
binding does the right thing.
Upvotes: 1
Reputation: 3907
Since your selectedPhoto
is observable you have to add parenthesis before accessing observable's properties:
<h4 id="myModalLabel" data-bind="text: selectedPhoto().PhotoText "></h4>
...
<img data-bind="attr: { src: selectedPhoto().BlobUrlPhoto }" id="full-modal-img" alt="" />
Update:
Another way you may prefer is using with
binding that sets binding context to given variable (either plain or observable). So add it to #full-modal-photopage:
<div class="modal fade" id="full-modal-photopage" data-bind="with: selectedPhoto" ...
and access properties without specifying selectedPhoto
:
<h4 id="myModalLabel" data-bind="text: PhotoText "></h4>
...
<img data-bind="attr: { src: BlobUrlPhoto }" id="full-modal-img" alt="" />
Upvotes: 2