1

我是淘汰赛的新手。我无法理解示例中的一个技巧。这是我的代码。我创建了 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) {
});

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

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

f_martinez

这是因为您计算的 updateCallback 取决于整个用户 observableArray。这种依赖似乎是隐含的,但它是通过 callback(self);...

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

当我在更新中 使用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 ......我只使用简单的空循环并且不改变内部的任何东西......

4

2 回答 2

0

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

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

对于每个新用户,您还可以在内部创建新的计算,这个计算取决于数组。所以数组中有两个用户意味着这个数组中的任何变化都会触发两个计算。

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

  1. 构造函数再创建一个计算值,它在创建后立即计算(输出 3),并且
  2. 数组更改并且所有先前创建的计算再次评估(输出 1、2、3)。

更新

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

这是整个淘汰赛的非常酷和简单的概念。顺便说一句,官方 KO 文档中有一篇关于依赖跟踪的好文章。

于 2017-05-17T14:20:02.760 回答
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

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

f_martinez谢谢你!

于 2017-05-18T10:27:57.307 回答