У меня проблема с перекрестным обновлением с нокаутом. Следующая функция («self.applyTagsAllocation») вызывает некоторый странный эффект. Строка 3: 'scenetag.sceneID = scene.sceneID;' обновляет «tag.sceneID», а также локальную переменную scenetag. Я действительно не могу понять, почему, поскольку сценарий никогда не является наблюдаемым.Проблема с перекрестным обновлением с нокаутом
self.applyTagsAllocation = function (tag) {
var scenetag = tag;
var scene = self.selectedScene();
scenetag.sceneID = scene.sceneID;
scene.sceneTags.push(scenetag);
};
Далее мы приводим более полный перечень моих ViewModel:
var Tag = function (data) {
var self = this;
self.ID = data.ID || -1;
self.sceneID = data.sceneID;
self.text = ko.observable((data.text || 'new').trim());
self.tagType = ko.observable(data.tagType || -1);
}
var Scene = function(data){
var self = this;
self.sceneID = data.sceneID;
self.sceneTags = ko.observableArray();
self.tags = ko.computed({
read: function() {
var tags = [];
tags.push.apply(tags, self.sceneTags());
return tags;
},
write: function (tag) {
this.sceneTags.push(tag);
},
owner: self
});
};
var ViewModel = function (model){
var self = this;
self.selectedScene = ko.observable();
self.sceneTags = ko.observableArray();
self.Scenes = ko.observableArray(
ko.utils.arrayMap(model, function (item) {
return new Scene(item);
}));
self.sceneTags = ko.computed(function() {
var tags = [];
ko.utils.arrayForEach(self.Scenes(), function (scene) {
tags.push.apply(tags, scene.tags());
});
return tags;
});
//Tag is first created with:
self.addSceneTag = function (name, type) {
if (!type) type = -1;
var newtag = new Tag({
ID: -1,
sceneID: self.selectedScene().sceneID,
text: name,
tagType: type
});
// already in use?
var abort = false;
ko.utils.arrayForEach(self.selectedScene().sceneTags(), function (tag) {
if (tag.text() === newtag.text()) abort = true;
});
if (!abort) self.selectedScene().sceneTags.push(newtag);
};
self.applyTagsAllocation = function (tag) {
var scenetag = tag;
var scene = self.selectedScene();
scenetag.sceneID = scene.sceneID;
scene.sceneTags.push(scenetag);
};
};
(Вы можете спросить, почему «Сцена» имеет как sceneTags-массив и теги-массив Это потому, что я сделал. .. упрощение в этом примере в моем проекте у меня есть еще один тег типа и два типа объединяется в ViewModel-Scope)
HTML
Tag сначала устанавливаются с:
<input class="taginput" placeholder="<add a tag>" data-bind="textInput: tagname, event: {keyup: $root.inputTag}" />
Тогда, когда тег существует, я хочу, чтобы добавить его на другую «сцену» из сферы «Еогеасп: тег» с:
<span data-bind="visible: sceneID !== null && sceneID !== $root.selectedScene().sceneID, click: function(){$root.applyTagsAllocation($data)};">Add Tag</span>
Фактическое Еогеасп здесь есть цикл в knockout- (от Райана Нимейера):
<div class="tag-list" data-bind="sortable:{template:'tagsTmpl',data:$root.sceneTags"></div>
Что может быть причиной этого? Любые подсказки и подсказки высоко оценены!
Thanx заранее!
Hi @Tyblitz! Большое спасибо за ваш ответ. Ваше предложение с клонированием, похоже, делает трюк. Brilliant. Я так благодарен! :) –
Просто подумал о другом возможном подходе: вместо клонирования я мог бы использовать «тег» для создания нового тега-объекта с теми же атрибутами, кроме self.selectedScene(). SceneID, не так ли? Тогда я, вероятно, должен переписать «self.addSceneTag», чтобы включить обе функции. –
@AsleG, что вы могли бы сделать; В вашем конструкторе вы можете сделать var var = function (data, flag) {self.sceneID = flag === true? data.sceneID || ''; 'Если вы не хотите включать его в конструктор, вы можете создать новый тег со всеми реквизитами' var x = new Tag (data); 'и повторно назначить идентификатор сцены после этого, например' x.sceneID = '' 'или если вы хотите полностью удалить опору' delete x.sceneID'. – Tyblitz