Ответ 1
Наиболее распространенным шаблоном для этого в Knockout является установка метода selectChild на родителя, который принимает дочерний элемент. В большинстве случаев фактический ребенок не должен знать, что он выбран.
Затем в вашей привязке вы можете привязываться к $root.selectChild
или $parent.selectChild
. Первым аргументом, переданным обработчику, связанному с привязкой к клику/событию, являются фактические данные (в KO 2.0), поэтому ваш метод может жить на родительском объекте и получать его в качестве первого аргумента.
var Item = function(id, name) {
this.id = id;
this.name = ko.observable(name);
};
var ViewModel = function() {
var self = this;
this.items = ko.observableArray([
new Item(1, "one"),
new Item(2, "two"),
new Item(3, "three")
]);
this.selectedItem = ko.observable();
this.selectItem = function(item) {
self.selectedItem(item);
};
};
В этом случае ваша привязка будет выглядеть так:
<ul data-bind="foreach: items">
<li>
<a href="#" data-bind="text: name, click: $root.selectItem"></a>
</li>
</ul>
Здесь он находится в jsFiddle: http://jsfiddle.net/rniemeyer/anRsA/
Вы даже можете упростить его. Наблюдаемые функции - это функции, и первый аргумент, который вы передаете им, используется для установки их значения, поэтому вы даже можете не включать метод selectItem
и просто привязываться к $root.selectedItem
напрямую (будет выглядеть так: http://jsfiddle.net/rniemeyer/anRsA/1/). Обычно я использую отдельный метод, чтобы быть явным, чтобы дать ему правильное имя (действие), и в случае, если есть дополнительная обработка, которая должна быть выполнена до или после установки элемента.
До KO 2.0 (где $root
и $parent
были введены вместе с изменением для передачи данных в качестве первого аргумента для обработчиков click
и event
), я использовал первый метод, который вы предложил совсем немного. Одна вещь, которую вы можете сделать там, на самом деле не создает дочернее свойство (this.parentSelectedItem
) и просто ссылается на parentSelectedItem
(который был передан как аргумент) непосредственно в методе select
, поскольку он будет доступен в функции, потому что созданного замыкания.