【问题标题】:KnockoutJS: Access index of item in array from within the JavaScript templateKnockoutJS:从 JavaScript 模板中访问数组中项目的索引
【发布时间】:2012-09-02 02:10:04
【问题描述】:

我使用 KnockoutJS 从数组中填充一个列表:

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

为了将其用于进一步处理。

【问题讨论】:

    标签: indexing knockout.js ko.observablearray


    【解决方案1】:

    您可以创建一个自定义绑定,将您的属性设置为索引,它看起来像:

    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/

    【讨论】:

    • 非常感谢您及时详细的回答,尤其是对于 jsfiddles!在尝试使用自定义绑定的第一个选项时,我注意到数据绑定可以访问“myIndex”,但在数组的初始填充期间,我无法在列表项的 javascript 模板中访问它。关于为什么会这样的任何指示?
    • 在这种情况下,在应用绑定之前,索引不会设置到您的对象上。因此,在应用绑定之前运行的任何代码都不可用。如果您在此之前需要它,那么您可能需要考虑其他选项。
    • 谢谢。目前,第一个选项应该没问题,但如果我需要提前访问,我会记住这一点。
    猜你喜欢
    • 2011-08-28
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-18
    • 2019-03-11
    相关资源
    最近更新 更多