Does anybody know how I'd accomplish the following pattern with knockoutJS? I use this pattern all the time in apache flex and want to see if I can mimic it. I am unsure how to replace an observable with another. Any help/thoughts much appreciated.
//model
myViewModel = {
items : ko.observableArray(),
selected_item : ko.observable()
}
//view
<h3 data-bind="text : myViewModel.selected_item.name"> </h3>
<ul>
<!-- ko foreach: myViewModel.items -->
<li data-bind="text : name"/>
<!-- /ko -->
</ul>
//logic
$('li').click(function(e){
//check ko.dataFor(this) has different id from that of myViewModel.selected_item
//if id different
//set myViewModel.selected_item to ko.dataFor(this)
//rejoice as h3 text changes
})
You are on the right track. There are a few patterns that you can use to choose a selected item. If you want to attach a click handler unobtrusively, as you have above, then your best bet would be to use a delegated handler, so that you are set to handle changes to your observableArray. A delegated handler will be able to handle new elements being added.
So, you could do something like:
Here is a sample: http://jsfiddle.net/rniemeyer/hBUBN/
When you bind to your
h3
, sinceselected_item
can be null you would need to protect yourself by wrapping it in awith
block (in the example), calling a function that handles null, or doing it in the binding like (data-bind="text: myViewModel.selected_item() ? myViewModel.selected_item().id : 'unknown'"
). To keep it clean, this logic can be put in a function and you can call the function from your data-bind or usingwith
prevents this from being an issue (although it renders nothing when it is null).Otherwise, you can even just do this:
The
click
(andevent
) binding in KO 2.0 pass the current data as the first argument. You can use the$parent
variable to access one scope level up (or$root
to get to the base level). Observables are functions and you set their value by passing the new value as the first argument. So, doing$parent.selected_item
here will call the observable function passing your data as the first argument. So, it will set your selected value to the proper item.Sample: http://jsfiddle.net/rniemeyer/gemug/