Как вручную вызвать oniteminvoked в WinJS ListView

#javascript #listview #windows-store-apps #winjs

#javascript #listview #windows-магазин-приложения #winjs

Вопрос:

У меня есть WinJS ListView, элементы которого созданы с использованием функции шаблона ( itemTemplate опция указывает на функцию). Возвращаемый элемент имеет внутри него div, который имеет win-interactive класс, чтобы он мог принимать входные данные. В частности, этот div должен иметь возможность прокручивать, чтобы показать больше содержимого, которое может поместиться в элементе ListView.

Прокрутка отлично работает с win-interactive классом, применяемым к div. Проблема, которую я пытаюсь решить, заключается в том, что обычный щелчок (мышь вниз, мышь вверх) по-прежнему вызывает oniteminvoked событие в ListView, в то же время позволяя прокручивать div внутри элемента ListView.

Я подумал, что это будет легко: я бы привязал прослушиватель событий щелчка к div с win-interactive классом и просто передал это событие щелчка другому элементу элемента ListView, гарантируя, что в конечном итоге oniteminvoked событие будет запущено.

Я привязал прослушиватель кликов к win-interactive div, и он запускается, как и ожидалось. Однако я не могу понять, как вызвать вызов щелчка / элемента в другой части элемента ListView. Я пытался использовать свойства события (currentTarget) для получения родительских или родственных элементов и запуска событий для них, но я просто не могу понять, как вызвать событие для такого элемента, как event.currentTarget .

tl; dr: Как я могу разрешить прокрутку внутри элемента ListView, при этом разрешая обычное нажатие для запуска вызова элемента?

Ответ №1:

В целом, ListView просто обрабатывает клики, передавая их любому itemInvoked обработчику, который вы регистрируете для элемента управления. Это означает, что вы должны иметь возможность просто обойти всю эту цепочку и вызвать ваш обработчик напрямую с соответствующим индексом элемента, который легко получить.

В обработчике щелчков вашего элемента, если у вас есть удобный объект ListView, тогда list.CurrentItem будет элементом с фокусом (и, очевидно, тем, на который нажат), а его свойство index будет тем, что обычно передается в itemInvoked . С помощью этого вы можете вызвать свой itemInvoked обработчик напрямую, создав соответствующий объект события, или вы можете разделить код вашего обработчика на другой метод и вызвать его вместо этого.

В качестве основного примера, начиная с проекта шаблона приложения Grid, я добавил win-interactive к элементу item-title (который может быть любым другим, например, вашей областью прокрутки) в pages/groupedItems/groupedItems.html:

 <h4 class="item-title win-interactive" data-win-bind="textContent: title"></h4>
  

В готовом методе pages/groupedItems/groupedItems.js , я прикрепил объект ListView к элементу управления страницей для последующего использования:

 var listElement = element.querySelector(".groupeditemslist");
var list = listElement.winControl;
this._list = list;
  

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

 var that = this;

list.addEventListener("loadingstatechanged", function () {
    if (list.loadingState == "complete") {
        var interactives = element.getElementsByClassName("item-title");

        for (var i = 0; i < interactives.length; i  ) {
            interactives[i].addEventListener("click", that._itemClick.bind(that));
        }
    }
});
  

Реализация _itemClick в элементе управления my page выглядит следующим образом:

 _itemClick: function (e) {
    var item = this._list.currentItem;

    //Can also get the index this way
    var index = this._list.indexOfElement(e.currentTarget);

    this._itemInvoked({"detail" : { itemIndex : item.index} })
},
  

где this._itemInvoked — это тот же обработчик, который поставляется с шаблоном.

Обратите внимание, что с win-interactive вы не получаете обычного поведения pointerDown / pointerUp для элементов, которые выполняют небольшую анимацию вниз / вверх, поэтому вы можете включить их тоже, если сочтете это важным (используя методы WinJS.UI.Animation.pointerDown / pointerUp для создания эффектов).

Наконец, вероятно, можно подняться по цепочке от элемента e.currentTarget внутри _itemClick и имитировать событие щелчка на соответствующем родительском элементе, но я думаю, что это больше проблем, чем того стоит, если проследить через код WinJS, который все это делает. Гораздо проще просто вызвать свой собственный itemInvoked .