2016-02-22 3 views
2

Я пытаюсь связать событие click с элементом списка. Когда я нажимаю на элемент списка ниже, он должен запустить функцию updateCurrent в javascript, но ничего не делает.knockout 'click' binding not working

Примечание: Я использовал $parent.updateCurrent как я нахожусь в currentCat контексте, когда я звоню функция и функция updateCurrent находится в ViewModel контексте.

HTML:

<div id="wrap" data-bind="with: currentCat"> 

    <div id="names"> 
     <ul data-bind="foreach: $parent.catNames"> 
      <!--Here, clicking on name doesn't fire updateCurrent--> 
      <li data-bind="text: $data, click: $parent.updateCurrent"></li> 
     </ul> 
    </div> 
</div> 

JS:

var viewModel = function() { 

    var self = this; 
    this.catNames = ko.observableArray([]); 
    this.catList = ko.observableArray([]); 

    //cats is defined as a simple array of objects, having name 
    cats.forEach(function(catObject) { 
     self.catList.push(new cat(catObject)); 
     self.catNames.push(catObject.name); 
    }); 

    //initially, set the currentCat to first cat 
    this.currentCat = ko.observable(this.catList()[0]); 

    //should run when the user click on the cat name in the list 
    this.updateCurrent = function() { 
     console.log("hello"); 
    } 

}; 

Я не получаю ошибку, когда я нажимаю на имя списка, но консоль ничего не войти.

Я считаю, что я не использую контекст должным образом, но не могу понять здесь точный вопрос. Любая помощь будет оценена.

+2

Try $ корень вместо $ родителя –

+0

Это сделали волшебство! Большое спасибо @ViktorKukurba – akshayKhot

+0

Хмм, интересный вопрос. Комментарий ВиктораКукурбы - это быстрое решение, но я совершенно удивлен, что KO не может решить '$ parent', как ожидал OP (и I). – Jeroen

ответ

0

Вы находитесь в двух уровнях контекста. Переплет with указывает, что $data внутри этого div - currentCat. foreach обеспечивает еще один уровень контекста. $parent не относится к родительскому объекту, а к контексту вне этого контекста. Вы можете использовать $parents[1].

Когда вы говорите $parent.catNames, вы только внутри with контекста, так это обратиться к catNames в ViewModel, так как нет никакого другого ограждающего контекста. Но где вы говорите $parent.updateCurrent, вы выпрыгиваете из контекста foreach до with. И ты хотел прыгнуть еще один.

+0

Ой, поэтому, когда я говорю «parent.catNames», родитель не ссылается на ViewModel? то где он указывает, контекст currentCat? но это ViewModel, не так ли? – akshayKhot

+0

См. Обновленный ответ. –

3

Когда вы говорите $ parent.catNames, вы ссылаетесь на ViewModel, потому что это свойство, принадлежащее непосредственному родительскому элементу в иерархии. С привязкой foreach вы находитесь в новом контексте; поэтому в $ parent.updateCurrent непосредственным родителем в иерархии становится элемент в массиве catNames.

$ parent равен $ parents [0], который является одним из имен cat. $ parents [1] будет ссылаться на ViewModel.

Почему бы не использовать $ root?

Нокаут будет поддерживать ваш DOM и контекст привязки гораздо глубже, чем может быть легко видно. В привязках шаблонов $ root-контекст может ссылаться на объект, который даже не в шаблоне HTML!

<div data-bind="template: { name: 'sample', data: catNames }"></div> 
<script type='text/html' id='sample'> 
    <!-- ko foreach: $data --> 
    <span data-bind="text: 'Cat ' + $index + ' of ' + $parents[0].length"></span> 
    Returns "Cat 1 of 10" 
    <!-- /ko --> 

    <!-- ko foreach: $data --> 
    <span data-bind="text: 'Cat ' + $index + ' of ' + $root.length"></span> 
    Return "Cat 1 of undefined" because ViewModel has no length property! 
    <!-- /ko --> 
</script> 

Binding контекст документация: http://knockoutjs.com/documentation/binding-context.html

+1

+1 '$ root' гниет, и ИМО никогда не должны были быть включены (или, по крайней мере, нести живое предупреждение о здоровье). Использование корня эффективно означает создание зависимости от формы глобального масштаба (обычно потому, что разработчик не удосужился узнать, как работают нокауты). По мере роста проекта соблазн использовать «$ root» в качестве свалки для всего, что должно быть в сфере видимости, может стать очень ядовитым. – spender