4

私は最近問題に苦しんでいました。私はそれを解決しましたが、より良い解決策がないかどうかわからないので、コメントをいただければ幸いです。

問題。「ScrollIntoView」バインディングを作成したかったのです。要素をビューにスクロールするには DOM-Element が必要なので、いつでも好きなときに明示的にトリガーしたいカスタムバインディングを作成しました。私はこのコードから始めました:

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 オブザーバブルを再トリガーします。うーん!

だから私はこのパターンを考え出し、カスタムバインディングを次のように拡張しました:

    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

4

3 に答える 3

7

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/を参照してください

于 2015-07-06T13:07:52.157 に答える