Reputation: 11731
I have a viewModel which contains an observable folder
object (undefined on initialization)
I have a foreach
template that should display the files of the folder, which is not working.
Html
<div data-bind="template: { if: currentFolder(), foreach: currentFolder.files }">
<div style="padding: 10px; border: 1px solid #000; background-color: #f0f0f0">
<span data-bind="text: $data"></span>
</div>
</div>
<button type="button" id="button">Set current folder</button>
Javascript
var viewModel = {
currentFolder: ko.observable()
};
ko.applyBindings(viewModel);
document.getElementById('button').onclick = addCurrentFolder;
function addCurrentFolder() {
var folder = {
files: [ "File 1", "File 2", "File 3" ]
};
viewModel.currentFolder(folder);
// does nothing
console.log(viewModel.currentFolder());
};
Upvotes: 0
Views: 1404
Reputation: 1752
You have to do data-bind with either observable or observableArray. I have created fiddle for you.
And your html code should be as follows,
<div data-bind="foreach: currentFolder">
<div style="padding: 10px; border: 1px solid #000; background-color: #f0f0f0">
<span data-bind="text: $data"></span>
</div>
</div>
Since I am binding "currentFolder" with "foreach", knockout is expecting currentFolder as an observableArray. So you have to change view model as follows,
var viewModel = {
currentFolder: ko.observableArray()
};
And then push values to observable array as follows,
viewModel.currentFolder.pushAll([ "File 1", "File 2", "File 3" ])
Fiddle: http://jsfiddle.net/hV89w/12/
EDIT:
You have to change "currentFolder" as an observableArray. Right now, currentFolder().files can render what you want. However, This is not recommended. Because, It wont capture file level changes. I mean, the UI wont update, on doing currentFolder().files.push("File N")
.
And if you want to update UI, then you have to do like as follows,
var folder = currentFolder();
folder.files.push("File N");
viewModel.currentFolder(folder);
This approach is make all UI refresh. I mean, this will refresh whole UI in following HTML. This process is consider as costlier.
<div data-bind="foreach: currentFolder">
<div style="padding: 10px; border: 1px solid #000; background-color: #f0f0f0">
<span data-bind="text: $data"></span>
</div>
</div>
Upvotes: 0
Reputation: 5063
Try and execute your currentFolder observable in the foreach
foreach: currentFolder().files
Upvotes: 0
Reputation: 15003
Your foreach
binding needs to be foreach: currentFolder().files
since currentFolder
is an observable containing an object and as such it needs to be invoked in order to "unwrap" its contents.
Upvotes: 1