2012-12-06 18 views
2

在我的視圖模型有文件,文件類型和未使用的文件類型的列表:beforeChange手動訂閱的knockoutjs與奇怪的行爲

viewModel = 
    files: ko.observableArray([ 
     new File({name: "A1", id: 1}) 
     new File({name: "B1", id: 2}) 
     new File({name: "C1", id: 3}) 
     new File({name: "D1", id: 4}) 
    ]) 
    types: ko.observableArray(dataTypes) 
    typesUnused: ko.observableArray(dataTypes) 

我創建了一個File類,並在它的type屬性。 爲了填補未使用的文件類型列表中,有一個訂閱beforeChange和其他改動後的type財產

class File 
    constructor: (data) -> 
    @name = data.name 
    @id = data.id 
    @type = ko.observable(null) 

    # Updates array of types not used 
    @type.subscribe ((oldValue) -> 
     console.log "OLD: #{oldValue}" 
     viewModel.typesUnused.remove (item) -> item is oldValue if oldValue 
    ), @, "beforeChange" 
    @type.subscribe (newValue) ->   
     console.log "NEW: #{newValue}" 
     if newValue && viewModel.typesUnused.indexOf(newValue) < 0 
     viewModel.typesUnused.push newValue 

理念
的想法是,只要更改文件類型,將發生改變之前的事件被觸發並在未使用的文件類型列表中添加舊類型。另外一個事件會在更改後發生,它會從未使用的類型列表中刪除新類型。

問題

  1. 所有的文件附帶的文件類型的定義的陣列中的第一種類型。在這種情況下,「jpeg」
  2. 通過更改文件類型,所有其他人都遭受改變!
  3. 當您從列表typesUnused中刪除文件類型時,types列表也可能被更改!

參見:http://jsfiddle.net/4nyVE/2/

+0

對不起,我應該問 - 這應該重新標記的CoffeeScript?我很困惑了一下,看着那個jsfiddle。 – xdumaine

回答

2

您的問題是,你的typestypesUnused與同一陣列dataTypes初始化。當從typesUnused中刪除項目時,這也會影響types,因爲它們包含對同一陣列的引用。

此時,其他選擇中當前選定的選項不再有效(不再位於types),因此該值設置爲第一選項。

你最好的選擇可能是與原數組的副本(myarray.slice(0)是複製一個簡單的方法),如初始化typesUnused

typesUnused: ko.observableArray(dataTypes.slice(0))