Knockoutjs:ScrollIntoViewTrigger

joe*_*rgi 4 triggers custom-binding knockout.js

我最近遇到了一个问题,虽然我为我解决了这个问题,但我不确定那里是否有更好的解决方案,所以我很感激任何评论.

问题.我想创建一个'ScrollIntoView'绑定.由于将一个元素滚动到视图中,需要DOM-Element,我编写了一个自定义绑定,然后我想明确地触发它,只要我满意.我从这段代码开始:

ko.bindingHandlers.scrollTo = {
    update: function (element, valueAccessor, allBindings) {
        var _value = valueAccessor();
        var _valueUnwrapped = ko.unwrap(_value);
        if (_valueUnwrapped) {
            element.scrollIntoView();
        }
    }
Run Code Online (Sandbox Code Playgroud)

};

绑定:

<div data-bind="scrollTo: goToThis">
Run Code Online (Sandbox Code Playgroud)

在ViewModel中我有这个可观察的:

_self.goToThis = ko.observable(false).extend({notify: 'always'});
Run Code Online (Sandbox Code Playgroud)

然后我可以通过调用触发:

_self.goTohis(true);
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.但是我很快遇到了问题.因为每当我将goTothis()Observable设置为true时,真正的值就会停留在它上面,导致一些元素滚动到视图中,而用户没有明确地触发它.例如,当我更改视图时,基本上用if绑定隐藏所有元素,然后切换回来,if绑定将重新触发之前已设置为true的所有goToThis observable.啊!

所以我想到了这个模式并扩展了我的custum绑定,如下所示:

    ko.bindingHandlers.scrollTo = {
        update: function (element, valueAccessor, allBindings) {
            var _value = valueAccessor();
            var _valueUnwrapped = ko.unwrap(_value);
            if (_valueUnwrapped) {
                element.scrollIntoView();
// resets the trigger value to false. Otherwise there will be more and more ViewModels, where the value is true.
                if (ko.isWriteableObservable(_value) && typeof (_valueUnwrapped) === 'boolean') {
                    _value(false);
                }
            }
        }
   };
Run Code Online (Sandbox Code Playgroud)

每次触发时基本上重置布尔值.

所以我想我的问题是:有没有人写过scrollIntoView绑定?如果是的话,你是怎么解决的?

通常,是否存在编写触发器的模式?即我只是想触发绑定,但没有真正的价值变化.

最好的问候j

sro*_*oes 7

你的scrollTo处理程序是这样的:

ko.bindingHandlers.scrollTo = {
    update: function (element, valueAccessor, allBindings) {
        var _value = valueAccessor();
        var _valueUnwrapped = ko.unwrap(_value);
        if (_valueUnwrapped) {
            element.scrollIntoView();
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

但是不是使用goToThis可观察的每个视图模型,更好的是在你的根中有1个observable,它跟踪当前的滚动项,然后在你的绑定中传递一个表达式,如下所示:

<div data-bind="scrollTo: $root.scrolledItem() == $data">
Run Code Online (Sandbox Code Playgroud)

这样您就不需要重置任何内容,并且您不需要goToThis每个视图模型的可观察对象.

http://jsfiddle.net/290ew0nr/1/