KnockoutJS - Observable Array属性更新,应更改父级的状态

时间:2015-05-13 07:44:05

标签: knockout.js

我想更改person属性“father”的数组,然后应该更改父级的状态,但它不起作用。    我使用了ko.computed update“person's property father”,然后父母的“status”应该改为“true”。

我做错了什么?

<ul data-bind="foreach:vm">
        <li>
            <input type="text" data-bind="value:name" />
            <input type="text" data-bind="value:age" />
            <input type="text" data-bind="value:status" />
            <!-- ko foreach:person-->
                <input type="text" data-bind="value:father" />
            <!-- /ko -->
        </li>
    </ul>

<script type="text/javascript">
    var ps = [{"name":"gsh","status":false,"age":12,"person":[{"father":"a"},{"father":"b"}]},{"name":"zx","status":false,"age":"22","person":[{"father":"c"},{"father":"d"}]}];

    function Person(p){
        this.father=ko.observable(p.father);
    }

    function Pros(p){
        this.name = ko.observable(p.name);
        this.age = ko.observable(p.age);    
        this.person = ko.utils.arrayMap(p.person,function(pe){
            return new Person(pe);
        });     
        this.status = ko.observable(p.status);
        this.status = ko.computed(function(){
            ko.utils.arrayForEach(this.person,function(pe){
                pe.father();    
            });

            return true;
        },this);
    }
    var vm = ko.utils.arrayMap(ps,function(p){
        return new Pros(p);
    });
    var VModel = ko.observableArray(vm);

    ko.applyBindings(VModel);
</script>

1 个答案:

答案 0 :(得分:0)

我发现有三个问题:首先,你要覆盖status属性:

this.status = ko.observable(p.status);
this.status = ko.computed(function(){});

这不仅没有达到预期的效果,而且覆盖可观察量非常危险,因为它会导致不容易追踪的错误。例如,如果将<input>绑定到observable,然后用其他东西覆盖该observable,则绑定将默默地停止工作。

此外,ko.utils.arrayMap返回普通数组,而不是ko.observableArray。这意味着this.person无法被观察到,并且迭代它的computed将不会注意到是否添加或删除了元素。这个可能可以在你的情况下工作,如果你正确的时间,不添加或删除任何东西,但这是要记住的事情。

第三个问题是你的computed也可能不符合你的要求:

this.status = ko.computed(function(){
  ko.utils.arrayForEach(this.person,function(pe){
    pe.father();    
  });

  return true;
},this);

这会迭代所有人,丢弃结果然后总是返回true。

总之,我会尝试像这样重写你的代码:

var ps = [{"name":"gsh","status":false,"age":12,"person":[{"father":"a"},{"father":"b"}]},{"name":"zx","status":false,"age":"22","person":[{"father":"c"},{"father":"d"}]}];

function Person(p){
    this.father=ko.observable(p.father);
}

function Pros(p){
    this.name = ko.observable(p.name);
    this.age = ko.observable(p.age);
    this.person = ko.observableArray([]);

    ko.utils.arrayForEach(p.person, function(pe){
      this.person.push( new Person(pe) );
    }, this);

    this.status = ko.computed(function(){
        var allTrue = true;

        ko.utils.arrayForEach(this.person(), function(pe){
            if (!pe.father()) {
              allTrue = false;
            }
        });

        return allTrue;
    },this);
}

var vm = ko.utils.arrayMap(ps,function(p){
    return new Pros(p);
});

var VModel = ko.observableArray(vm);

如果您不需要对早于9的Internet Explorer的支持,则可以在Array.every的帮助下更简洁地编写您的status计算:

this.status = ko.computed(function(){
  return this.person().every(function(p) {
    return p.father();
  });
}, this);