Функция knockoutjs afterRender в привязке foreach
Я пытаюсь указать входной эффект на вставленные элементы, используя привязку knockoutjs foreach. Очень простая настройка:
myViewModel.myObservableArray.push({enter:function() { ... });
и в разметке:
foreach:{data:myObservableArray, afterRender:enter}
похоже, что он должен работать... правильно? Но он не находит функцию ввода в элементе. То, что я нашел, работает:
myViewModel.enter = function(something, item) { item.enter(); };
foreach:{data:myObservableArray, afterRender:$root.enter}
добавление функции ввода в модель корневого представления и привязка afterRender
к $root.enter. Затем Enter передает элемент как свой второй параметр, поэтому он может в свою очередь вызвать функцию ввода элемента, но он чувствует себя как взлома.
Может ли кто-нибудь объяснить, что здесь происходит?
Спасибо.
EDIT:
Чтобы уточнить, я создал fiddle.
Это очень просто и более подробно описано в анимированном переходе. Он запускает функцию в модели корневого представления для каждого элемента dom, который вставлен с использованием привязки foreach.
Итак, вопрос в том, что, если мне нужны функции itemRender, afterAd или beforeRemove? Я мог видеть, что это полезно. Особенно, если использовать привязку шаблона для динамического выбора шаблона (примечание 4). Есть ли чистый способ сделать это? Прямо сейчас у меня есть функция enter
в корне модели представления, которая просто вызывает функцию enter
на элементе, но, как я уже сказал выше, это похоже на взлом.
Ответы
Ответ 1
Нет, это способ он был разработан.
Из Documenation:
Примечание 3: Использование "afterRender", "afterAdd" и "beforeRemove"
Иногда вам может потребоваться запустить пользовательскую логику пост-обработки на элементах DOM, сгенерированных вашими шаблонами. Например, если вы используете библиотеку виджетов JavaScript, такую как пользовательский интерфейс jQuery, вы можете перехватить выходные данные шаблонов, чтобы вы могли запускать на нем команды jQuery UI, чтобы преобразовать некоторые из визуализированных элементов в сборщики дат, слайдеры или что-то еще.
Как правило, лучший способ выполнить такую пост-обработку на элементах DOM - это написать пользовательскую привязку, но если вы действительно просто хотите доступ к необработанным элементам DOM, испускаемым шаблоном, вы можете использовать afterRender.
Передайте ссылку на функцию (либо литерал функции, либо укажите имя функции в вашей модели представления), а нокаут вызовет ее сразу после рендеринга или повторного рендеринга вашего шаблона.
(Акцент мой)
Как говорится, пользовательская привязка - это еще один способ сделать это, и может быть лучше в зависимости от того, что делает эта функция enter()
.
Ответ 2
underscore debounce (_.debounce) - отличное решение в этом случае.
шаблон
data-bind=" template: {foreach:myObservableArray, afterRender: runWhenAllRenderDone }
функция debounce будет выполнена, если afterRender не запущен за последние 100 миллисекунд.
var runWhenAllRenderDone = _.debounce(myFunction, 100);
function myFunction(){
//do some task but do it for once only
}
is't it awesome?