2015-01-29 2 views
1

У меня есть следующий код:Нокаут: Обработка событий на Foreach элементов

<div id="resultlist" data-bind="foreach: content"> 
    <ul style="list-style-type:none;"> 
     <li> 
      <div class="result" data-bind="event:{ mouseover:myfunction, mouseout:myFunction2}"> 

       <div class ="resultlisticoncontainer"> 
        <div class="resultcontenttypeIcon myclassHidden" data-bind="css: { myclassVisible: newClass() == true, myclassHidden: newClass() == false }"> 
         <object id="contentIcon" data="img/File_Icon_24x24.svg" type="image/svg+xml" width="100%" height="100%"></object> 
        </div> 

        <div class="resultcontenttypeIcon myclassHidden" data-bind="css: { myclassVisible: newClass() == true, myclassHidden: newClass() == false }> 
         <object id="marple" data="img/Glass_Icon_24x24.svg" type="image/svg+xml" width="100%" height="100%"></object> 
        </div> 
       </div> 

       <p><span data-bind="text: name" class="filenamestlye"></span></p> 
       <p><span data-bind="text: file_path" class="urlstyle"></span></p> 
       <p><span data-bind="html: highlight" ></span></p> 
      </div>  
     </li> 
    </ul> 
</div> 

Так что я хочу сделать, это, когда я поставил мышь на DIV с «результат» класса, дивы с классом " resultcontenttypeIcon "должен стать видимым. Это прекрасно работает, но проблема в том, что это происходит с каждым дочерним элементом div, созданным с помощью цикла foreach. Так что я хочу, что только дочерние div наведенного div становятся видимыми, так что наведение на событие не запускается для каждого div. Я думаю, проблема в том, что значение newClass становится истинным для всей модели viewmodel.

Это мой ViewModel код:

function ItemListViewModel() { 

    newClass= ko.observable(true); 
    myfunction = function() { 
     newClass(true); 

    }, 
    myFunction2= function(){ 
     newClass(false);   
    }, 
} 
ko.applyBindings(new ItemListViewModel()); 
+2

Вы считали, что используете только CSS: классы hover, чтобы скрыть/показать результат? Это было бы проще и быстрее. – Quango

+0

Спасибо, что делает трюк. Я дал «результат» div: hover .resultcontenttypeIcon {display: block; } style и resultcontenttypeIcon отображение стиля: none ;. Поэтому, если я нахожу «результат», отображается дочерний div. – AKR

ответ

1

Я думаю, что вы могли бы найти CSS проще, чтобы это произошло. Вот JSFiddle, который делает то, что я думаю, что вы хотите. Я заменил объекты изображениями, чтобы заставить его работать на экране. Очевидно, макет разбит, поскольку у нас нет вашего CSS.

http://jsfiddle.net/Quango/010vn1ra/

Метод довольно прост: класс будет скрыт определяется как display: none по умолчанию.

Затем мы добавляем :hover в класс result, который изменяет display дочернего класса. Это означает, что для этого вам не нужны привязки.

+0

Спасибо, тоже. Уже изменил его на версию стиля css. Работает правильно. – AKR

0

Селекторы CSS :hover действительно работают хорошо, если у вас нет зависимостей, которые изменяются, с какими элементами перемещается. Но если, например, вы хотите отобразить текст с индексом элемента в списке где-то еще, измените шаблон или вызовите функцию, вам все равно нужно связать событие.

Мы можем предотвратить элемент, к которому событие должно было «поглотить» на события благодаря параметрам Нокаут проходит связанно функции: data & event. С небольшой целевой проверки, ваша функция контейнера Mouseover выглядит следующим образом:

app.updateHovered = function(data,e) { 
    var target = e.target || e.srcElement, 
    // ko.contextFor passes the context of the object, including the $index observable 
     index = ko.contextFor(target).$index(); 
    // the following check depends on your elements of course 
    if (target.nodeName === 'DIV' && target.parentNode.nodeName === 'DIV') 
     app.isVisible(index); // isVisible holds the currently 'selected index' 
}; // and a simple 'false' setter on mouse out 
app.removeHovered = function(data, e) { 
    app.isVisible(false); 
} 

Пример HTML для выше:

<div data-bind="foreach: list, event: { mouseover: updateHovered, mouseleave: removeHovered }"> 
    <div> 
     <span data-bind="text: $index, visible: $index() === $parent.isVisible()"></span> 
    </div> 
</div> 
<h3 data-bind="text: typeof isVisible() === 'number' ? 'Howdy, you selected item ' + isVisible() : ''"></h3> 

Смотрите очень простой demo, в котором isVisible свойство содержит $ индекс последнего измененного списка.

Фактически речь идет о делегировании событий, поэтому вы также можете проверить привязку R. Niemeyer Knockout-delegatedEvents, которая автоматизирует этот процесс для вас.

Смежные вопросы