2015-06-22 2 views
3

Мне удалось немного разобраться с проектом, над которым я работаю.Нокаут нескольких привязок на вложенных элементах dom

Первоначально сайт имеет одну страницу, на которой используется нокаут, а на других страницах используется jQuery. Из-за некоторых проблем с модулем Foundation, помещенным в корень элемента body, я в итоге применил привязки для viewmodel для этой страницы к элементу body.

Быстрая перемотка вперед 4 месяца, и, не предвидя проблемы, я сейчас нахожусь, я пошел и перестроил нашу корзину покупок в Нокауте. Корзина покупок видна на каждой странице и включается частично с ZF2.

Возвращаясь к странице я работал 4 месяца назад, он полностью порвали с сообщением об ошибке в консоли говоря:

Uncaught Error: You cannot apply bindings multiple times to the same element. 

Вот код, чтобы показать мой макет:

<html> 
    <head> 
     <title>My Website</title> 
    </head> 
    <body> // 4 month old SPA bound here 
     <nav> 
      <div id='shopping-basket'> // Shopping basket bound here 
       ... 
      </div> 
     </nav> 
     <div id='my-app'> 
      ... 
     </div> 
    </body> 
</html> 

JavaScript:

var MyAppViewModel = function() { 
    // logic 
}; 

var ShoppingBasketViewModel = function() { 
    //logic 
}; 

ko.applyBindings(new MyAppViewModel(), document.body); 
ko.applyBindings(new ShoppingBasketViewModel(), document.getElementById('shopping-basket'); 

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

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

Есть ли когда-либо, когда я применяю привязки, чтобы у меня были оба режима просмотра, работающие бок о бок, будучи вложенными в Dom и оставаясь независимыми друг от друга?

+0

укажите код knockoutjs –

+0

да, вы можете использовать второй параметр 'ko.applyBinings' как ваш идентификатор div', который разрешает проблему. я надеюсь, что 'shopping-basket' ​​&' my-app' - 2 divs правильно? –

+0

Извините, добавлено javascript, чтобы выделить точку.Проблема в том, что перемещение оригинального SPA в отдельный контейнер прерывает приложение, и это невозможно, что означает, если это возможно, оба приложения должны оставаться в контейнере, в котором они сейчас находятся. –

ответ

2

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

1) Добавить пользовательскую привязку, так что вы можете пропустить связывание на конкретной корзине:

ko.bindingHandlers.stopBinding = { 
    init: function() { 
     return { controlsDescendantBindings: true }; 
    } 
}; 
ko.virtualElements.allowedBindings.stopBinding = true; 

2) Добавьте пользовательские привязки в вашем HTML (окружать корзине):

<html> 
<head> 
    <title>My Website</title> 
</head> 
<body> // 4 month old SPA bound here 
    <nav> 
     <!-- ko stopBinding: true --> 
     <div id='shopping-basket'> // Shopping basket bound here 
      ... 
     </div> 
     <!-- /ko --> 
    </nav> 
    <div id='my-app'> 
     ... 
    </div> 
</body> 

3) Применить привязки, как вы уже делаете:

ko.applyBindings(new MyAppViewModel(), document.body); 
ko.applyBindings(new ShoppingBasketViewModel(), document.getElementById('shopping-basket'); 

4) Первое связывание пропустит корзину покупок из-за вашего специального обработчика привязки, и ваше второе связывание явно привяжет корзину покупок.

Я не проверял код выше на вашем конкретном примере, но он должен указывать вас в правильном направлении.

+0

Спасибо, я попробую! –

+0

Слова не могут выразить мою благодарность за это, могут подтвердить, что это сработало и спасло меня от ужаса! –

+0

Рад, что я мог помочь! – gkempkens

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