2016-05-19 37 views
0

我有這個KnockoutJS組件,我需要在同一頁上有多個實例。我遇到了不同實例似乎共享可觀察屬性的問題。所以如果其中一個textareas被更新,同一頁面上的其他人也會被更新。KnockoutJS - 組件 - 多個實例

我試圖在不同的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>' 
}); 

視圖模型,完成後的模板將在外部文件。

如果我在上面放置了3-4個組件的實例,它似乎只是最後一個「有效」的實例。

試圖谷歌這個問題了幾個小時,但沒有成功:(

希望有人能告訴我正確的方法!

+0

什麼'params'你傳球?例如:在您使用'this.notes = params.notes'的viewModel構造函數中。這意味着如果'params.notes'是傳遞給多個組件的可觀察對象,它將是一個共享屬性。 – user3297291

+0

不同實例的標記看起來像這樣(它是傳遞給notes/showNote的不同observable)。 http://pastebin.com/nvCxWPPb –

+0

我並不完全確定有什麼問題,但這就是我所指的:https://jsfiddle.net/t76722qu/請注意'text'在構造函數中被初始化,因此_unique_給每個組件_instance_。 'shared'通過'params'傳遞,因此被_all_組件共享。 (嘗試點擊'true' /'false'來查看它對所有組件的改變) – user3297291

回答

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>' 
}); 

享受:)