2013-06-01 2 views
0

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

В моем приложении SPA, построенном с нокаутом и дурандалом, я сильно полагаюсь на конструкцию With knockoutJS. Что-то, что сильно заложено во всем ядре как шахтных, так и дурандальных архитектур.

Многие действия идут со связанными с ними маршрутами, чтобы сохранить предыдущее действие в истории браузера. Теперь действие также может манипулировать DOM или инициировать переход CSS (например, задание класса во внутреннем div, который запускает переход).

К сожалению, каждый раз, когда привязка перепроверяется, вся DOM под этим выражением перестраивается, тем самым отменяя мои изменения DOM и переходы на убийство. Это именно то, что происходит в моем сценарии, который что-то вроде следующего псевдо:

<div data-bind="with: myViewModel"> 
    ... print current datetime .... 
</div> 
... 
myViewModel(myViewModel()); 

Пожалуйста, смотрите эту jsfiddle для более конкретного примера такого поведения: http://jsfiddle.net/k32Xf/

Эта проблема только с конструкцией, однако Я не нашел способ обойти его, кроме как взломать сам дурандальный код. Это ошибка в нокауте? что будет предлагаемым решением/обходным решением?

Спасибо!

+0

Я ничего не вижу Дюраннал, связанный с jsfiddle. – RainerAtSpirit

+0

Правильно, настоящая проблема imo в нокауте, но durandal kinda заставляет вас использовать определенную архитектуру, которая вызывает эту проблему. В основном я использую перенаправление маршрута и функцию активации моей модели просмотра для принятия соответствующих действий, однако этот же маршрут заставляет мой HTML перестроить. – Polity

+0

Можете ли вы использовать fork https://github.com/dFiddle/dFiddle-1.2 и создать скрипку того, как вы используете Durandal в этом контексте? – RainerAtSpirit

ответ

1

Если ваши myViewModel наблюдаемые изменения, то действительно все в пределах with будет перестроено. Это единственный способ заставить его работать.

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

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

Таким образом, вы сможете решить свою проблему, предоставив пользовательский equalComparer, который использует ссылочное равенство. Это так же просто, как:

myViewModel.equalityComparer = function (a, b) { return a === b; }; 

Вот модифицированная версия вашего jsFiddle показывая это на практике: http://jsfiddle.net/CFhkT/1/

А вот больше информации о том, почему они выбрали для реализации равенства объектов они, как они сделали: Why does Knockout.js's default equality comparer treat non-primitive types as not equal?

+0

Я вижу, спасибо за это! Я попытаюсь посмотреть, смогу ли я использовать это как решение – Polity

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