knockoutjs afterRender проблема в версии 2, не очевидная в версии 1.2.X - PullRequest
4 голосов
/ 08 января 2012

Я недавно обновил существующий проект до KnockoutJS 2.0 из KnockoutJS 1.2.1 (хотя я запустил его, используя предыдущую версию).После обновления я заметил, что afterRender запускается до того, как элементы фактически полностью попадают в html.

Я немного осмотрелся, и мне кажется, что это целевое поведение в соответствии с несколькими другими вопросами, связанными с этим.area:

Почему в afterRender элементы div шаблона отображаются как ": hidden"?

Проблема проявляется в Jquery Validate, где я применяю некоторые правила к элементам и сообщаетМне, что элементы не существуют.Странно то, что раньше это нормально работало в 1.2.1.Я не уверен, что это потому, что afterRender обрабатывался по-другому в предыдущих версиях или изменения в общей системе шаблонов приводят к тому, что он ведет себя по-другому ...

Если произошли изменения или это предполагаемое поведениеЕсть ли способ узнать, когда элементы шаблона фактически вошли в HTML, где они должны быть?Я знаю, что загруженные элементы передаются обратно через аргументы обратных вызовов afterRender, но безопасно ли их использовать для чего-либо контекстуального с манипуляциями Dom на этом этапе?

Edit

Я собрал примерМоя конкретная проблема: Пример проекта, показывающего проблему

Если вы посмотрите на логику afterRender для каждого шаблона, он просто выполняет некоторую простую проверку, но всякий раз, когда вы пытаетесь использовать элементы, он просто взрывается.Однако, если вы возьмете логику проверки, она будет работать нормально.

Я более чем рад поднять руки, если я сделал что-то не так и попытаться это исправить, но я, честно говоря, не знаю, в чем проблемаесть, так как все работает изолированно ...

Ответы [ 3 ]

3 голосов
/ 10 января 2012

Проблема в том, что внешний механизм шаблонов асинхронно загружает шаблон и первоначально использует шаблон «загрузки».Это означает, что ваши afterRender функции вызываются дважды.Движок в настоящее время не имеет возможности запускать afterRender только после использования реального шаблона.Я посмотрю, что потребуется для добавления поддержки.

Некоторые опции, которые у вас есть: * функциям afterRender передается массив элементов в качестве первого аргумента.Вы можете проверить массив, чтобы увидеть, содержит ли он ваши настоящие элементы.

- иначе, в вашем коде подключения, вы можете проверить, существуют ли ваши элементы, прежде чем делать вызовы проверки.

Итак,Ваши функции будут вызваны дважды.Вам просто нужно убедиться, что в первый раз вы не выполняете код, который требует присутствия элементов DOM.

1 голос
/ 23 января 2012

Я являюсь автором внешнего механизма шаблонов, который @Grofit использует в опубликованном им примере приложения.Я обновил проект, чтобы он обернул вызов afterRender в функцию, которая сначала проверяет, был ли установлен «загруженный» логический флаг внешнего источника шаблона в значение «истина».Я разместил обновленную версию примера проекта здесь .

Райан. Мне бы очень хотелось, чтобы вы высказались по этому поводу, если есть лучшее решение, которое я должен использовать.Это казалось лучшим вариантом ....

0 голосов
/ 10 января 2012

После долгих копаний выясняется, что проблема связана с рамками загрузки шаблонов и потому, что они асинхронные ... и это по какой-то причине не обрабатывается должным образом, поэтому нокаут запускает событие дважды ...

В идеале я хотел бы по-прежнему использовать асинхронную загрузку, но я не уверен, что для этого потребуется изменить Knockout или внешние привязки ... или, может быть, оба ...

...