Knockout JS - 计算值

时间:2017-05-17 03:08:25

标签: knockout.js callback computed-field

我是Knockout的新手。我无法理解在例子中找到的一个技巧。在这里我的代码。我创建了3个用户......下面显示我创建第三个用户时的处理输出。

// It's my view
<div id="page-container">

<input type="text" data-bind="value: usernameInput" />
<button data-bind="click: addPerson">Добавить</button>

<ul data-bind="foreach: users">
    <li data-bind="text: username"></li>
</ul>

</div>

<script>
// It's my UserModel
function UserModel(username, callback){
    console.log('Start creating object...');
    var self = this;
    self.username = ko.observable(username);
    self.updateCallback = ko.computed(function(){
        console.log('updateCallback: ' + self.username());
        callback(self);
        return true;
    });
};

// It's my ViewModel
function ViewModel(){
    var self = this;
    self.users = ko.observableArray([]);
    self.usernameInput = ko.observable('');

    self.addPerson = function(){
        var u = self.usernameInput();
        var um = new UserModel(u, self.update);
        self.users.push(um);
        console.log('Item Pushed');

        self.usernameInput('');
        console.log('Users Collection: ' + self.users());
    };

    self.update = function(item){
        console.log('Update: ' + item.username());
        ko.utils.arrayFilter(self.users(), function(it) {
        });
    };
};

ko.applyBindings(new ViewModel(), document.getElementById('page-container'));

这是我的控制台输出。

Start creating object...
updateCallback: 3
Update: 3
updateCallback: 1
Update: 1
updateCallback: 2
Update: 2
updateCallback: 3
Update: 3
Item Pushed
Users Collection: [object Object],[object Object],[object Object]

这部分我理解

Start creating object...
updateCallback: 3
Update: 3

但是当我尝试在updateCallback上下文中的update方法中调用此函数时:

ko.utils.arrayFilter(self.users(), function(it) {
});

为每个用户计算updateCallback 3次......

任何人都可以解释“手指上”为什么会发生这种情况......提前感谢您的回复...

f_martinez

  

这是因为你的updateCallback计算取决于整个用户   observableArray。这种依赖关系似乎是隐含的,但它已经创建了   通过回调(自我); ...

是的,这种依赖是隐含的......但这种依赖性对我来说还不清楚......

当我在更新中使用 LOOP 时,如下所示: for(var i in self.users()){} 它为每个用户计算了updateCallback 3次...但是如果我删除循环并创建第三个用户......我只会得到这个输出:

Start creating object...
updateCallback: 3
Update: 3
Item Pushed
Users Collection: [object Object],[object Object],[object Object]

我无法理解 updateCallback 如何依赖于整个用户observableArray ...我只使用简单的空LOOP并且不会更改内部的任何内容...

2 个答案:

答案 0 :(得分:0)

这是因为你的updateCallback计算取决于整个users observableArray。这种依赖关系似乎是隐含的,但它是通过callback(self);创建的,它在下一级堆栈中有表达式:

ko.utils.arrayFilter(self.users(), ...)`

对于每个新用户,您还可以创建新的计算内部,并且此计算取决于数组。因此,在数组中有两个用户意味着此数组中的任何更改都将触发两个计算。

所以...当你添加第三个用户时:

  1. 构造函数创建一个计算结果,在计算后立即计算(输出3)和
  2. 数组发生变化,所有先前创建的计算结果再次评估(输出1,2,3)。
  3. <强>更新

    无论您是否更改了计算中的observable或observableArray。如您所知,observable和可观察数组实际上是函数。因此,如果您调用内部的任何observable,则会跟踪此调用以创建依赖项。

    这是整个Knockout非常酷而简单的概念。顺便说一下,官方KO文档中有good article about dependency tracking

答案 1 :(得分:0)

我明白了!我试着解释一下吧!

我添加了一些有用的例子!见吼!

<强>第一

<div id="page-container">

    <input type="text" data-bind="value: usernameInput" />
    <button data-bind="click: addPerson">Add</button>
    <button data-bind="click: pushObject">Dependency</button>

    <ul data-bind="foreach: users">
        <li data-bind="text: username"></li>
    </ul>

</div>

<script>

    function UserModel(username, dependency){
        console.log('Start creating object...');
        var self = this;
        self.username = ko.observable(username);
        self.updateCallback = ko.computed(function(){
            console.log(username);
            dependency();
            return self.username();
        });
    };

    function ViewModel(){
        var self = this;
        self.dependency = ko.observableArray([]);

        self.users = ko.observableArray([]);
        self.usernameInput = ko.observable('');

        self.addPerson = function(){
            var u = self.usernameInput();
            var um = new UserModel(u, self.dependency);
            self.users.push(um);
            console.log('Item pushed');
            self.usernameInput('');
        };

        self.pushObject = function(){
            self.dependency.push({});
        };
    };

</script>

我的控制台输出:

Start creating object...
1
Item pushed
Start creating object...
2
Item pushed
Start creating object...
3
Item pushed
1
2
3

<强>第二

<div id="page-container">

    <input type="text" data-bind="value: usernameInput" />
    <button data-bind="click: addPerson">Add</button>
    <button data-bind="click: setString">Dependency</button>

    <ul data-bind="foreach: users">
        <li data-bind="text: username"></li>
    </ul>

</div>

<script>

    function UserModel(username, dependency){
        console.log('Start creating object...');
        var self = this;
        self.username = ko.observable(username);
        self.updateCallback = ko.computed(function(){
            console.log(username);
            dependency();

            return self.username();
        });
    };

    function ViewModel(){
        var self = this;
        self.users = ko.observableArray([]);
        self.usernameInput = ko.observable('');

        self.dependency = ko.observable();

        self.addPerson = function(){
            var u = self.usernameInput();
            var um = new UserModel(u, self.dependency);
            self.users.push(um);
            console.log('Item pushed');
            self.usernameInput('');
        };

        self.setString = function(){
            self.dependency('');
        };
    };

</script>

我的控制台输出:

Start creating object...
1
Item pushed
Start creating object...
2
Item pushed
Start creating object...
3
Item pushed
1
2
3

我认为在用户集合中推送项目之前重新计算值。但实际上它重新计算后的项目推送到用户集合中。这是关键点!!!还有两个很好的学习例子!!!

f_martinez 谢谢你!