我有这个KnockoutJS组件,我需要在同一页面上有多个实例。我遇到了不同实例似乎共享可观察属性的问题。因此,如果更新了其中一个textareas,则同一页面上的其他文本也会更新。
我试图在不同的textareas上设置唯一的id作为测试,但这并没有解决它。
这是我的组件代码:
ko.components.register('note-editor', {
viewModel: (params) => {
var self = this;
this.id = uid.new('note-editor-');
this.title = ko.observable(params && params.title || '');
this.titleClass = ko.observable(params && params.titleClass || '');
this.expandTooltip = ko.observable(params && params.expandTooltip || '');
this.numberOfCharactersLeft = ko.observable(params && params.numberOfCharactersLeft || '');
this.limitCharacters = ko.observable(params && params.limitCharacters || 1000);
this.showNote = params.showNote;
this.notes = params.notes;
this.showIcon = ko.computed(() => {
return self.notes() != undefined && self.notes() != '';
});
this.notesCount = ko.computed(() => {
var value = self.notes(),
charLimit = self.limitCharacters();
if (value) {
var characters = charLimit - value.length;
if (characters < 0) {
return 0;
}
return characters;
}
return charLimit;
});
},
template: '<div data-bind="text: title, attr: { class: titleClass }"></div>'
+ '<div tabindex="1" data-bind="toggleButton: showNote, attr: { title: expandTooltip }" class="toggleButton"></div><img data-bind="visible: showIcon" src="https://placeholdit.imgix.net/~text?txtsize=5&txt=30%C3%9730&w=20&h=20" style="margin-bottom: -7px" />'
+ '<div class="note-counter" data-bind="visible: showNote, style: { fontWeight: notesCount() == 0 ? \'bold\' : \'\' }">'
+ '<span data-bind="text: notesCount()" > </span><span data-bind="text: numberOfCharactersLeft"></span>'
+ '</div>'
+ '<textarea data-bind="visible: showNote, value: notes, valueUpdate: [\'input\', \'afterkeydown\'], limitCharacters: limitCharacters, attr: { id: id, name: id }" tabindex="1"></textarea>'
});
完成后,viewmodel和模板将位于外部文件中。
如果我在上面放置了3-4个组件的实例,那么它似乎只是“工作”的最后一个实例。
试图谷歌这个问题几个小时,但没有成功:(
希望有人能告诉我正确的方法!
答案 0 :(得分:0)
所以,经过无数个小时我找到了解决方案。我不得不使用createViewModel工厂模式。如果没有使用,那么viewmodel将被用作单例实例,这就是我的问题。
我真的不喜欢单身模式是默认的。如果需要,我可以使用createViewModel工厂模式实现单例模式。
无论如何,它已经解决了所以我认为我应该在这里发布我的解决方案,以寻找其他任何答案:)
function noteViewModel(params) {
var self = this;
self.id = uid.new('note-editor-');
self.title = ko.observable(params && params.title || '');
self.titleClass = ko.observable(params && params.titleClass || '');
self.expandTooltip = ko.observable(params && params.expandTooltip || '');
self.numberOfCharactersLeft = ko.observable(params && params.numberOfCharactersLeft || '');
self.limitCharacters = ko.observable(params && params.limitCharacters || 1000);
self.showNote = params.showNote;
self.editorNotes = params.notes;
self.showIcon = ko.computed(() => {
return self.editorNotes() != undefined && self.editorNotes() != '';
});
self.notesCount = ko.computed(() => {
var value = self.editorNotes(),
charLimit = self.limitCharacters();
if (value) {
var characters = charLimit - value.length;
if (characters < 0) {
return 0;
}
return characters;
}
return charLimit;
});
}
ko.components.register('note-editor', {
viewModel: (params) => {
createViewModel: return new noteViewModel(params);
},
template: '<div data-bind="text: title, attr: { class: titleClass }"></div>'
+ '<div tabindex="1" data-bind="toggleButton: showNote, attr: { title: expandTooltip }" class="toggleButton"></div><img data-bind="visible: showIcon" src="https://placeholdit.imgix.net/~text?txtsize=5&txt=30%C3%9730&w=20&h=20" style="margin-bottom: -7px" />'
+ '<div class="note-counter" data-bind="visible: showNote, style: { fontWeight: notesCount() == 0 ? \'bold\' : \'\' }">'
+ '<span data-bind="text: notesCount()" > </span><span data-bind="text: numberOfCharactersLeft"></span>'
+ '</div>'
+ '<textarea data-bind="visible: showNote, value: editorNotes, valueUpdate: [\'input\', \'afterkeydown\'], limitCharacters: limitCharacters, attr: { id: id, name: id }" tabindex="1"></textarea>'
});
享受:)