【问题标题】:Updating list item using foreach Knockout binding使用 foreach 敲除绑定更新列表项
【发布时间】:2013-12-20 16:23:53
【问题描述】:

淘汰网站有一个使用 foreach 绑定添加和删除列表项的绝佳示例,但是您将如何更新这些值?我在下面的小提琴中尝试过这样做,但是 DOM 元素没有响应我的更新:http://jsfiddle.net/SC5Lw/1/

<ul data-bind="foreach: people">
    <li>
        Name at position <span data-bind="text: $index"> </span>:
        <span data-bind="text: name"> </span>
        <a href="#" data-bind="click: $parent.removePerson">Remove</a>
        <a href="#" data-bind="click: $parent.updatePerson">Update</a>
    </li>
</ul>

var person1 = ko.observable({ name: 'Bert' });
var person2 = ko.observable({ name: 'Charles' });
var person3 = ko.observable({ name: 'Denise' });

self.people = ko.observableArray([person1, person2, person3]);

...

self.updatePerson = function(person) {
    for(var i = 0 ; i < self.people.length ; i++)
    {
        if(self.people[i].name === person.name)
        {
            self.people[i].name = 'Bob';
        }
    }
};

我已经将 observableArray 的元素本身变成了 observables,所以我不确定为什么它们绑定的元素不会对视图模型中的属性更改做出反应。

【问题讨论】:

  • 显示您的 HTML 与您的绑定

标签: knockout.js


【解决方案1】:

您需要做的是为具有ko.observable 的人创建一个名为name 的类。这不是你在这里所做的。您已将person1 设为可观察的,但它包含一个对象字面量,其中包含一个名为name 的普通属性。

类似这样的:

function Person(name) {
    var self = this;
    self.name = ko.observable(name);
}

现在在您的父虚拟机中:

var person1 = new Person('Bert');
var person2 = new Person('Charles');
var person3 = new Person('Denise');

self.people = ko.observableArray([person1, person2, person3]);

这是一个有效的fiddle

另外,我不会打扰你的循环来找到匹配的person。您已经拥有此人,因此只需在此处更改其财产即可。

所以而不是这个(无论如何都不起作用,因为people 是一个函数,而不是一个属性):

self.updatePerson = function(person) {
    for(var i = 0 ; i < self.people.length ; i++)
    {
        if(self.people[i].name === person.name)
        {
            self.people[i].name = 'Bob';
        }
    }
};

你可以这样做:

self.updatePerson = function(person) {
    person.name("Bob");
}

您甚至可以通过将此函数移至您的 Person 视图模型并在那里执行此操作来使其更简洁:

function Person(name) {
    var self = this;
    self.name = ko.observable(name);
    self.updateMe = function() {
        self.name("Bob");
    }
}

这避免了在 foreach 循环中绑定 $parent

    <a href="#" data-bind="click: updateMe">Update</a>

这里有一个 fiddle 也有这些更新。

【讨论】:

  • 你在 JSFiddle 中有这个工作吗?我似乎无法让它工作:jsfiddle.net/SC5Lw/3
  • @user3123391:是的,我加了一个小提琴。您还有许多其他问题也需要解决。特别是当你使用observableArray 时,你不能使用myObservableArray.length,因为myObservableArray 是一个函数。你需要myObservableArray().length
  • 使用ko.observableArray 有时会让你感到困惑,因为你通常会在常规数组上找到的一些函数(例如pushremove)直接工作,但有些(@ 987654346@ 甚至索引数组)您需要获取底层数组。所以myObservableArray.push(item) 工作得很好,但myObservableArray[0] 不行。你需要myObservableArray()[0]。更糟糕的是,myObservableArray().push(item) 不起作用,因为你绕过了可观察的部分!
  • 谢谢!我仍然习惯于所有可观察到的功能。来自一个有点令人困惑的 C# 背景。
  • @user3123391:是的,需要一段时间才能习惯。这是因为旧版浏览器不支持 getterssetters 属性。
猜你喜欢
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
  • 2013-05-03
  • 2012-06-09
  • 1970-01-01
  • 2013-10-02
  • 2020-10-08
  • 2012-03-30
相关资源
最近更新 更多