Бесконечный цикл для tag-it, завернутый в выбивающий компонент
Я создал нокаутированную пользовательскую привязку, чтобы обернуть тег-it по предложению Droyad. Окончательный код (упрощенный):
ko.bindingHandlers.tagit = {
init: function (element, valueAccessor, allBindingsAccessor) {
var bind = function () {
valueAccessor().tagsList($(element).tagit("assignedTags"));
};
var options = $.extend({
afterTagAdded: bind,
afterTagRemoved: bind
}, valueAccessor().options || {});
// Create tags editor
$(element).tagit(options);
////// Block 1
var value = ko.utils.unwrapObservable(valueAccessor());
var tags = value.tagsList();
for(var x = 0; x < tags.length; x++) {
$(element).tagit("createTag", tags[x]);
}
////// End Block 1
},
////// Block 2
update: function (element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var tags = value.tagsList();
$(element).tagit("removeAll");
for(var x = 0; x < tags.length; x++) {
$(element).tagit("createTag", tags[x]);
}
}
////// End Block 2
};
Соответствующий HTML-код:
<div data-bind="with: currentDocument">
<input data-bind="tagit: {tagsList: tags}"></input>
</div>
Моя проблема: я должен использовать "Блок 1" и удалить "Блок 2", в противном случае компонент входит в бесконечный цикл. Без блока 2 тег-он отображает теги каждый раз, когда я изменяю документ (изменения currentDocument), и я могу редактировать теги вручную без проблем. Вместо этого, если я изменю currentDocument.tags программно, это изменение не визуализируется (очевидно). Если я удаляю блок 1 и добавляю блок 2, обратный вызов afterTagAdded запускается для каждого добавленного тега, который, в свою очередь, изменяет массив тегов, который запускает функцию обновления и так далее.
Есть идеи, как решить проблему? Я думаю, что обратные вызовы afterTagAdded и afterTagRemoved срабатывают только для ручных модификаций, а не для $(element).tagit("createTag", tags[x]); проблема может быть решена. Спасибо за вашу помощь!
1 ответ
Решение простое, хотя и не элегантное. Я определил переменную "loading", которая имеет значение true, если изменение вызвано загрузкой редактора тегов. Когда true блокирует наблюдаемое обновление. (В предыдущем коде удалите блок 1 и добавьте блок 2).
Попытка объяснить проблему на SO, как обычно, помогает мне найти решение. Спасибо также за это!
ko.bindingHandlers.tagit = {
loading: false,
init: function (element, valueAccessor, allBindingsAccessor) {
var bind = function () {
if(ko.bindingHandlers.tagit.loading) return;
valueAccessor().tagsList($(element).tagit("assignedTags"));
};
...
},
update: function (element, valueAccessor, allBindingsAccessor) {
// Load data
ko.bindingHandlers.tagit.loading = true;
var value = ko.utils.unwrapObservable(valueAccessor());
var tags = value.tagsList();
$(element).tagit("removeAll");
for(var x = 0; x < tags.length; x++) {
$(element).tagit("createTag", tags[x]);
}
ko.bindingHandlers.tagit.loading = false;
}