昏死。如何在可观察更新之前和之后执行自定义代码

时间:2017-09-21 13:17:46

标签: javascript html knockout.js

我有一组显示在页面中的用户。我有一对输入文本框来过滤名称和姓氏显示的用户。 我希望当输入文本字段中的任何值发生更改时,用户数组会更新。

以下是我必须实现的代码:

Knockout viewmodel:

function HomeViewModel() {
    var self = this;

    self.users = ko.observableArray([]);

    self.FilterByName = ko.observable('');
    self.FilterByLastName = ko.observable('');

    self.FilteredUsers = ko.observableArray([]);
    self.FilteredUsersComputed = ko.computed(function () {
        var result = self.users().filter(function (user) {
            return (user.name.toUpperCase().includes(self.FilterByName().toUpperCase()) &&
                user.lastName.toUpperCase().includes(self.FilterByLastName().toUpperCase())
            );
        });
        self.FilteredUsers(result);
    });

    $.getJSON("/api/User", function (data) {            
        self.users(data);
    });
}

ko.applyBindings(new HomeViewModel());

HTML:

        <div>
            <label>Name:</label>
            <input data-bind="textInput: FilterByName" />
        </div>
        <div>
            <label>Lastname:</label>
            <input data-bind="textInput: FilterByLastName" />
        </div>

(...)

        <div id="LLAdminBodyMain" class="container">
            <div class="row justify-content-center" data-bind="foreach: FilteredUsers">
                <div class="col-md-6 col-lg-4">
                    <p data-bind="text: name"></p>
                </div>
            </div>
        </div>

问题:

现在我想获得以下效果:

  1. 延迟执行FilteredUsers&#39;计算函数,以便每次在名称或姓氏字段中按下键时不触发。即:等到2秒钟没有按键事件;或者在按下后等待1或2秒钟来执行计算功能。
  2. 触发FilteredUsers时,首先淡出LLAdminBodyMain,然后更新FilteredUsers,然后使用新元素淡入LLAdminBodyMain
  3. 要做到这一点,我认为知道如何检测何时更新observable并在更新和传播新值之前执行我的自定义代码将有用。

    我尝试过类似的操作,但以下代码不起作用:淘汰赛不再检测到更改。

     self.FilteredUsersComputed = ko.computed(function () {
            console.log("In");
            $("#LLAdminBodyMain").fadeOut(function () {
                var result = self.users().filter(function (user) {
                    return (user.name.toUpperCase().includes(self.FilterByName().toUpperCase()) &&
                        user.lastName.toUpperCase().includes(self.FilterByLastName().toUpperCase())
                    );
                });
                self.FilteredUsers(result);
            }).delay(1000).fadeIn();
    
        });
    

    谢谢。

1 个答案:

答案 0 :(得分:0)

  

每次在名称或姓氏字段中按下某个键时,延迟执行FilteredUsers的计算函数。即:等到2秒钟没有按键事件;或者在按下后等待1或2秒钟来执行计算函数。

http://knockoutjs.com/documentation/rateLimit-observable.html。还有一个计算机可观察的最好只返回计算值而不是设置一个单独的可观察值。

self.FilteredUsers = ko.computed(function () {
    var result = self.users().filter(function (user) {
        return (user.name.toUpperCase().includes(self.FilterByName().toUpperCase()) &&
            user.lastName.toUpperCase().includes(self.FilterByLastName().toUpperCase())
        );
    });
    return result;
}).extend({ rateLimit: {timeout: 2000, method: "notifyWhenChangesStop"} });
  

当FilteredUsers被触发时,首先淡出LLAdminBodyMain,然后更新FilteredUsers,然后使用新元素淡入LLAdminBodyMain。

您需要使用afterAdd的{​​{1}}和beforeRemove回调。 请参阅http://knockoutjs.com/documentation/foreach-binding.html#note-7-post-processing-or-animating-the-generated-dom-elementshttp://knockoutjs.com/examples/animatedTransitions.html