2012-09-01 23 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