【问题标题】:Remove an item from nested observableArray从嵌套的 observableArray 中删除一个项目
【发布时间】:2014-10-07 05:00:25
【问题描述】:

嘿,我正在尝试从内部(嵌套)observableArray 中删除一个项目,如下所示,但删除按钮不起作用(对于内部 foreach 项目)。

http://jsfiddle.net/aDahT/1871/

html:

<h4>People</h4>
<ul data-bind="foreach: peoples">
    <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>
        <ul data-bind="foreach:people">
             <li>
                <span data-bind="text: $data"></span>
                 <button data-bind="click: $parent.deletePerson">Remove</button>
            </li>
        </ul>
    </li>
</ul>
<button data-bind="click: addPerson">Add</button>

脚本:

var Person = function(name, children){
 var self = this;
    self.name = name;
    self.people =  ko.observableArray(children);
    self.deletePerson = function() {
        alert(JSON.stringify(self));
        self.people.remove(this);
    }
}


function AppViewModel() {
    var self = this;

    self.peoples = ko.observableArray([
        new Person( 'Bert', ['baa', 'bbb'] ),
        new Person('Charles', ["caa", "cbb"] )
    ]);

    self.addPerson = function() {
        alert(this);
        self.peoples.push(new Person( "New" ,["Daa", "Dbb"] ));
    }.bind(this);

    self.removePerson = function() {

        self.peoples.remove(this);
    }
}

ko.applyBindings(new AppViewModel());

有人可以帮忙吗? 先谢谢了。

【问题讨论】:

    标签: knockout.js


    【解决方案1】:

    只需使用始终设置为当前视图模型的点击处理程序的第一个参数:

    self.deletePerson = function(viewModel) {
        self.people.remove(viewModel);
    }
    

    演示JSFiddle.

    Knockout 还将 this 设置为您的处理程序中的当前视图模型,但您的 deletePersonremovePerson 存在很大差异。

    removePerson 中,this 是一个对象(您的Person 对象),但在您的deletePerson 中,this 应该是一个原始类型:字符串

    但是,Knockout 使用 apply 调用您的函数并将原始类型装箱:JavaScript function call/apply with string

    如果您将this 注销到控制台,您会选中此项。你会看到类似的东西:

    String {0: "c", 1: "a", 2: "a", length: 3, [[PrimitiveValue]]: "caa"} 
    

    因此,您将在this 中的deletePerson 中结束一个装箱字符串,您需要使用valueOf()(或toString())来获取它的值:

    self.deletePerson = function() {
        self.people.remove(this.valueOf());
    }
    

    所以只要始终使用 KO 提供的第一个参数,它始终是原始值。

    【讨论】:

    • 谢谢!只是另一个问题,在这一行 alert(JSON.stringify(self));为什么它显示名称值而不显示人的值?
    • 因为JSON.stringify 只显示原始值,而people 是一个函数,因为它是一个可观察的数组。您需要使用ko.toJSON() 来获取人们的值,因此您需要编写:alert(ko.toJSON(self));
    • 谢谢,很有道理
    【解决方案2】:

    你也可以试试(jsfiddle):

    <ul data-bind="foreach:people">
    <li>
        <span data-bind="text: name"></span>
        <button data-bind="click: function() {$parent.people.remove($data)}, text: 'remove ' + name"></button>
    </li>
    </ul>
    
    var model = {
    people: ko.observableArray([{ name: "a"}, { name: "b"}, { name: "c"}])
    };
    
    ko.applyBindings(model);
    

    【讨论】:

      猜你喜欢
      • 2013-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-22
      • 1970-01-01
      • 2015-01-26
      相关资源
      最近更新 更多