Подтвердить что ты не робот

KnockoutJs v2.3.0: Ошибка Вы не можете применять привязки несколько раз к одному элементу

Я только что обновился до 2.3.0 и теперь получаю ошибку

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

что я не получил в 2.2.1.

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

Есть ли способ убрать это и избежать новой ошибки?

Вот мой код:

$.get(url + "GetAssignedCompaniesView?layoutId=" + layoutId + "&noCache=" + new Date().getMilliseconds(), function (result) {
              $("#editAssignedPartial").html($(result));
              showEditAssignedArea(true);
              $(window.document).ready(function () {
                 // error is thrown here
                 ko.applyBindings(self, window.document.getElementById("editAssigned"));
                 $("#layoutId").attr("value", layoutId);
                 updateTypeHiddenElement.attr("value", "companies");
      });
    });
<div id="editAssignedPartial">
</div>

$(document).ready(function () {
  'use strict';
  var vm = new Vm();
  ko.applyBindings(vm, document.getElementById("area1"));
});
4b9b3361

Ответ 1

Вам просто нужно удалить привязки, прежде чем снова использовать "applyBindings".

ko.cleanNode($element[0]);

должен сделать трюк. НТН.

Ответ 2

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

ko.applyBindings(myViewModel1, document.getElementById('element1'));
...
ko.applyBindings(myViewModel2, document.getElementById('element2'));

Теперь, когда оба элемента # element1 и # element2 не существуют, вы получите ошибку. Причина в том, что Knockout applyBindings возвращается к document.body как к корневому элементу, когда # element1 и # element2 не найдены. Теперь он пытается применить привязку дважды на теле...

Не замечательный запас нокаута, если вы спросите меня. Я предпочел бы ясное сообщение об ошибке, что элемент не существует в DOM (пока).

Надеюсь, это поможет некоторым людям.

Ответ 3

Вы не должны применять привязки более одного раза к представлению. В 2.2 поведение было undefined, но все еще не поддерживается. В 2.3 теперь он корректно показывает ошибку. При использовании нокаута цель состоит в том, чтобы применить привязки один раз к вашим представлениям на странице, а затем использовать изменения для наблюдаемых в вашей модели просмотра, чтобы изменить внешний вид и поведение вашего вида (ов) на вашей странице.

Ответ 4

Для работы над решениями важны две вещи:

  • При применении привязок вам нужно указать область (элемент)!!

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

Код ниже

Разметка

<div id="elt1" data-bind="with: data">
    <input type="text" data-bind="value: text1" >
</form>

Вид привязки

var myViewModel = {
  "data" : {
    "text1" : "bla bla"
  }
}:

Javascript

ko.applyBindings(myViewModel, document.getElementById('elt1'));

Очистить привязки

ko.cleanNode(document.getElementById('elt1'));

Ответ 5

Есть много отличных ответов для этой проблемы, но у меня есть ответ noobie.

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

Ответ 6

Я наконец решил свою проблему, вернув { controlsDescendantBindings: true } в функции init обработчика привязки. Увидеть это

Ответ 7

Если вы повторно используете элемент снова и снова (в моем случае используется модальный диалог начальной загрузки), вызов этой команды будет ko.applyBindings(el) несколько раз.

Вместо этого выполните одно из следующих действий:

if (!applied) {
    ko.applyBindings(el);
    applied = true;
}

Или вот так:

var apply = function (viewModel, containerElement) {
    ko.applyBindings(viewModel, containerElement);
    apply = function() {}; // only allow this function to be called once.
}

PS: Это может случиться чаще, если вы используете плагин сопоставления и преобразуете данные JSON в наблюдаемые.

Ответ 8

У меня возникла эта ошибка по другой причине.

Я создал шаблон для кнопок сохранения/отмены, которые я хотел бы показать вверху и внизу страницы. Сначала он работал, когда у меня был мой шаблон, определенный внутри типа < script type = "text/html" > element.... но потом я слышал, что вы могли бы при необходимости создать шаблон из обычного элемента DIV.

(Это работало лучше для меня с тех пор, как я использовал ASP.NET MVC, и ни один из синтаксиса @variableName Razor не выполнялся во время выполнения изнутри элемента script. Поэтому, перейдя на DIV, я все равно мог иметь двигатель MVC Razor генерировать HTML внутри моего шаблона KnockoutJs, когда страница загружается.)

После того, как я изменил свой шаблон для использования DIV вместо элемента script, мой код выглядел так..., который отлично работал на IE10. Однако позже , когда я тестировал его на IE8, он бросил это.

"Вы не можете применять привязки несколько раз к тому же элементу" ошибка.....

HTML

<div id="mainKnockoutDiv" class="measurementsDivContents hourlyMeasurements">

  <div id="saveButtons_template" style="display: none;">
    ... my template content here ...
  </div>

  <!--ko template: { name: 'saveButtons_template' } -->
  <!--/ko-->

  Some_HTML_content_here....

  <!--ko template: { name: 'saveButtons_template' } -->
  <!--/ko-->

</div>

JavaScript

ko.applyBindings(viewModel, document.getElementById('mainKnockoutDiv'));

РЕШЕНИЕ:

Все, что мне нужно было сделать, - это переместить мой saveButtons_template DIV вниз, чтобы он находился вне mainKnockoutDiv. Это решило проблему для меня.

Я предполагаю, что KnockoutJs пытался связать мой шаблон DIV несколько раз, так как он находился внутри целевой области applyBindings... и не использовал элемент script.... и ссылался как на шаблон.

Ответ 9

Я получал ту же ошибку в IE7/IE8. Работала отлично во всех других браузерах, включая IE9/IE10.

То, что я нашел, работало для меня - это устранение закрывающих тегов.

Bad

<div>
    <span data-bind="text: name"/>
</div>

Хорошо

<div>
    <span data-bind="text: name"></span>
</div>

Ответ 10

Обновленный ответ

Теперь, когда мы можем использовать dataFor() для проверки применения привязки, я бы предпочел проверить привязку данных, а не cleanNode() и applyBindings().

Как это:

var koNode = document.getElementById('formEdit');
var hasDataBinding = !!ko.dataFor(koNode);
console.log('has data binding', hasDataBinding);
if (!hasDataBinding) { ko.applyBindings(vm, koNode);}

Оригинальный ответ.

Уже много ответов!

Во-первых, допустим, довольно часто нам нужно выполнять привязку несколько раз на странице. Скажем, у меня внутри формы Bootstrap есть форма, которая будет загружаться снова и снова. Многие из форм ввода имеют двустороннюю привязку.

Я обычно выбираю легкий путь: очищать привязку каждый раз перед привязкой.

var koNode = document.getElementById('formEdit');
ko.cleanNode(koNode);
ko.applyBindings(vm, koNode);

Просто убедитесь, что здесь требуется koNode, поскольку для ko.cleanNode() требуется элемент узла, хотя мы можем опустить его в ko.applyBinding(vm).

Ответ 11

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

var segDiv =  $("#segments"); //did not exist, wrong id
var theDiv = segDiv.html("<div></div>");

ko.applyBindings(someVM, theDiv);

Насколько я могу судить, эта ошибка кажется немного перегруженной в том смысле, что она срабатывает по множеству различных ошибок, которые могут произойти с элементом, например, он не существует. Таким образом, описание ошибки может быть очень обманчивым. Вероятно, он должен был читать:

"Невозможность привязки привязки к элементу Возможные причины включают в себя: попытки множественного связывания, элемент не существующий, элемент не в иерархии DOM, причуды в браузерах и т.д.

Ответ 12

У меня была та же проблема, и я решил ее.

var vm = new MessagesViewModel()
ko.applyBindings(vm)

function ShowMessagesList() {
   vm.getData("MyParams")
}

setInterval(ShowMessagesList, 10000)

Ответ 13

ko.cleanNode($("#modalPartialView")[0]);
ko.applyBindings(vm, $("#modalPartialView")[0]);

работает для меня, но, как отмечают другие, cleanNode - это внутренняя функция ko, так что, возможно, есть лучший способ.