Knockoutjs:ScrollIntoViewTrigger [英] Knockoutjs: ScrollIntoViewTrigger

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

问题描述

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

问题.我想创建一个ScrollIntoView"绑定.由于将元素滚动到视图中,需要 DOM-Element,我编写了一个自定义绑定,然后我想在我高兴的时候显式触发它.我从这个代码开始:

ko.bindingHandlers.scrollTo = {更新:函数(元素,valueAccessor,allBindings){var _value = valueAccessor();var _valueUnwrapped = ko.unwrap(_value);如果(_valueUnwrapped){element.scrollIntoView();}}

};

绑定:

在 ViewModel 我有这个可观察的:

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

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

_self.goTohis(true);

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

所以我想出了这个模式并像这样扩展我的自定义绑定:

 ko.bindingHandlers.scrollTo = {更新:函数(元素,valueAccessor,allBindings){var _value = valueAccessor();var _valueUnwrapped = ko.unwrap(_value);如果(_valueUnwrapped){element.scrollIntoView();//将触发器值重置为 false.否则就会有越来越多的ViewModel,其中值为true.if (ko.isWriteableObservable(_value) && typeof (_valueUnwrapped) === 'boolean') {_值(假);}}}};

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

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

一般来说,是否有编写触发器的模式?即我只想触发一个绑定,但没有真正的值变化.

最好的问候j

解决方案

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

ko.bindingHandlers.scrollTo = {更新:函数(元素,valueAccessor,allBindings){var _value = valueAccessor();var _valueUnwrapped = ko.unwrap(_value);如果(_valueUnwrapped){element.scrollIntoView();}}};

但是,与其在每个视图模型中使用 goToThis observable,不如在根目录中有 1 个 observable 来跟踪当前滚动项,然后像这样在绑定中传递一个表达式:

这样你就不需要重置任何东西,也不需要每个视图模型的 goToThis observable.

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/

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

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