淘汰赛:ScrollIntoViewTrigger [英] Knockoutjs: ScrollIntoViewTrigger

查看:91
本文介绍了淘汰赛:ScrollIntoViewTrigger的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近一直在为一个问题而苦苦挣扎,尽管我为我自己解决了这个问题,但是我不确定是否还有更好的解决方案,所以我将不胜感激.

问题.我想创建一个'ScrollIntoView'绑定.由于将元素滚动到视图中需要DOM元素,因此我编写了一个自定义绑定,然后希望在需要时显式触发该自定义绑定.我从以下代码开始:

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

};

绑定:

<div data-bind="scrollTo: goToThis">

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

_self.goToThis = ko.observable(false).extend({notify: 'always'});

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

_self.goTohis(true);

到目前为止,太好了.但是我很快遇到了问题.由于每当我将goTothis()Observable设置为true时,true值就会停留在该值上,这会导致某些元素滚动到视图中,而无需用户明确触发它.例如,当我更改视图时,本质上使用if绑定隐藏了所有元素,然后又切换回去,如果if绑定将重新触发以前设置为true的所有goToThis可观察对象. gh!

所以我想出了这种模式并像这样扩展了我的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);
                }
            }
        }
   };

每次触发时都必须将布尔值重置.

所以我想我的问题是:有人写过scrollIntoView绑定吗?如果是,您是如何解决的?

通常,是否存在用于编写触发器的模式?即我只想触发绑定,但是没有实际值更改.

最好的问候 j

解决方案

您的scrollTo处理程序很好,像这样:

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

但是,与其在每个视图模型上使用goToThis可观察的模型,不如在根目录中保留1个可观察的模型,以跟踪当前滚动项,然后像这样在绑定中传递一个表达式:

<div data-bind="scrollTo: $root.scrolledItem() == $data">

这样,您无需重置任何内容,也不需要每个视图模型可观察的goToThis.

请参见 http://jsfiddle.net/290ew0nr/1/

i recently struggled with a problem and although i solved it for me, i'm not sure whether there aren't better solutions out there, so I'd appreciate any comments.

Problem. i wanted to create a 'ScrollIntoView' binding. Since scrolling an element into view, requires the DOM-Element, i wrote a custom binding, which i then wanted to explicitly trigger, whenever i pleased. I started with this code:

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

};

The binding:

<div data-bind="scrollTo: goToThis">

And in the ViewModel i had this observable:

_self.goToThis = ko.observable(false).extend({notify: 'always'});

which I then could just trigger by calling:

_self.goTohis(true);

So far, so good. However i quickly ran into Problems. Since whenever i set the goTothis() Observable to true, the true value stuck with it, which caused some of the elements to scroll into view, without the user explicity triggering it. For instance, when i changed the view, essentially hiding all the elements with an if binding, and then switched back, the if binding would re-trigger all the goToThis observables, which had previously been set to true. Ugh!

So i thought up this pattern and extended my custum binding like this:

    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);
                }
            }
        }
   };

Essentially resetting the boolean value each time it is triggered.

So i guess my question is this: Has anybody ever written a scrollIntoView binding? If yes, how did you solve it?

And generally, is there a pattern for writing triggers? ie i just want to trigger a binding, but there is no real value change.

best regards j

解决方案

Your scrollTo handler is fine like this:

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

But instead of working with a goToThis observable per view model, better would be to have 1 observable in your root which keeps track of the current scroll item and then pass an expression in your binding like this:

<div data-bind="scrollTo: $root.scrolledItem() == $data">

This way you don't need to reset anything and you don't need an goToThis observable per view model.

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

这篇关于淘汰赛:ScrollIntoViewTrigger的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆