2012-09-01 22 views
2

我使用KnockoutJS填充從數組列表:KnockoutJS:在數組從JavaScript的模板中項目的訪問索引

<div data-bind:"foreach: list"> 
    <input type="text" data-bind="value: myText" /> 
</div> 

function ViewModel() { 
    self.list = ko.observableArray([ 
     new listItem("sample text") 
    ]); 
}; 

function listItem (text) { 
    this.myText = text; 
}; 

我可以分配一個id,我輸入的單個實例,像這樣

<input data-bind="attr: { id: $index } ... 

如何從我的listItem函數中訪問此索引?我希望能夠做到像

function listItem (text) { 
    this.myText = text; 
    this.index = $index; 
}; 

爲了使用這個進一步處理。

回答

14

您可以創建一個自定義綁定,你的屬性設置爲索引,它看起來是這樣的:

ko.bindingHandlers.setIndex = { 
    init: function(element, valueAccessor, allBindings, data, context) { 
     var prop = valueAccessor(); 
     data[prop] = context.$index; 
    }   
}; 

這是假設你正在處理您的數組中的對象。你會使用它想:

<ul data-bind="foreach: items"> 
    <li data-bind="setIndex: 'myIndex', text: name"></li> 
</ul> 

因此,此份$index可觀察到與您指定的屬性名稱的對象。示例:http://jsfiddle.net/rniemeyer/zGmcg/

您可以在綁定之外執行此操作的另一種方式(這是我之前在$index之前執行的操作)是訂閱observableArray的更改並每次重新填充索引。

這裏是一個擴展的observableArray可能是什麼樣子:

//track an index on items in an observableArray 
ko.observableArray.fn.indexed = function(prop) { 
    prop = prop || 'index'; 
    //whenever the array changes, make one loop to update the index on each 
    this.subscribe(function(newValue) { 
     if (newValue) { 
      var item; 
      for (var i = 0, j = newValue.length; i < j; i++) { 
       item = newValue[i]; 
       if (!ko.isObservable(item[prop])) { 
        item[prop] = ko.observable(); 
       } 
       item[prop](i);  
      } 
     } 
    }); 

    //initialize the index 
    this.valueHasMutated(); 
    return this; 
}; 

你可以這樣使用它像:

this.myItems = ko.observableArray().indexed('myIndexProp'); 

這裏有一個例子:http://jsfiddle.net/rniemeyer/bQD2C/

+0

許多感謝提示和詳細的答案,特別是對於jsfiddles! 在嘗試使用自定義綁定的第一個選項時,我注意到'myIndex'可用於數據綁定,但在數組的初始填充期間,我無法在列表項的javascript模板中訪問它。任何指針爲什麼這是這種情況? – gzost

+0

在這種情況下,只有在綁定應用之後,索引纔會被設置到對象上。因此,應用綁定之前運行的任何代碼都不可用。如果您在此之前需要它,那麼您可能需要考慮其他選項。 –

+0

謝謝。目前,第一個選項應該沒問題,但如果我需要更早的訪問權限,我會記住這一點。 – gzost