2016-10-27 1 views
0

私はdom-repeatの再描画方法に問題があります。以下のスニペットは、単純なオブジェクト配列のフィルタリングと並べ替えがエンドユーザーに誤ったデータを提示する可能性があることを示しています。dom-repeatフィルタ/並べ替えの再描画エラー

これは、_applyFullRefreshメソッド(https://github.com/Polymer/polymer/blob/master/src/lib/template/dom-repeat.html#L482)内のインスタンスの再利用に関連すると判断しました。

このメソッドを変更して、一致するキーを使用してインスタンスを再利用することで、効果的なソリューションを作成できました。これのdiffはここで見ることができます:https://github.com/Polymer/polymer/compare/master...TomK:patch-1

私の質問:dom-repeatこの私が働い例を実現することができる唯一の方法にパッチですか?

スニペット期待される結果:フィルタ/並べ替え選択の任意の組み合わせで 、単一のライン(item contentx-item content)上の2つの番号は常に同じでなければなりません。ポリマー1.xでは

<!DOCTYPE html> 
 
<html> 
 
    <head> 
 
    <meta name="description" content="basic polymer jsbin"> 
 
    <meta charset="utf-8"> 
 
    <base href="//polygit.org/components/"> 
 
    <script src="webcomponentsjs/webcomponents-lite.js"></script> 
 
    <link rel="import" href="polymer/polymer.html"> 
 

 
    
 
    <dom-module id="x-item-test"> 
 
    <template> 
 
     x-item content: [[_innerText]] 
 
    </template> 
 
    <script> 
 
     HTMLImports.whenReady(
 
     function() 
 
     { 
 
      Polymer(
 
      { 
 
       is:   'x-item-test', 
 
       properties: { 
 
       _innerText: {type: String} 
 
       }, 
 
       attached:  function() 
 
          { 
 
           Polymer.RenderStatus.afterNextRender(this, this.__updateProp.bind(this)); 
 
           new MutationObserver(this.__updateProp.bind(this)) 
 
           .observe(this, {childList: true, subtree: true, characterData: true}); 
 
          }, 
 
       __updateProp: function() 
 
          { 
 
           var nodes = this.getEffectiveChildNodes(), output = ''; 
 
           for(var i in nodes) 
 
           { 
 
           var n = nodes[i]; 
 
           if(n.nodeType == 3 && n.nodeValue) 
 
           { 
 
            output += n.nodeValue; 
 
           } 
 
           } 
 
           this._innerText = output; 
 
          } 
 
      } 
 
     ); 
 
     } 
 
    ); 
 
    </script> 
 
    </dom-module> 
 

 
    <dom-module id="test-app"> 
 
    <template> 
 
     <div> 
 
     Filter <input type="checkbox" checked="{{_applyFilter::change}}"> 
 
     </div> 
 
     <div> 
 
     Sort <input type="checkbox" checked="{{_reverse::change}}"> 
 
     </div> 
 
     <template is="dom-repeat" items="[[actions]]" filter="{{_filter(_applyFilter)}}" sort="{{_sort(_reverse)}}"> 
 
     <div>Item content: [[item.id]] - 
 
      <x-item-test>[[item.id]] 
 
      <div>ignored</div> 
 
      </x-item-test> 
 
     </div> 
 
     </template> 
 
    </template> 
 
    <script> 
 
     HTMLImports.whenReady(
 
     function() 
 
     { 
 
      Polymer(
 
      { 
 
       is:   'test-app', 
 
       properties: { 
 
       actions:  { 
 
        type: Array, 
 
        value: [{id: '1', primary: true}, {id: '2'}, {id: '3', primary: true}, {id: '4'}] 
 
       }, 
 
       _applyFilter: {type: Boolean, value: false}, 
 
       _reverse:  {type: Boolean, value: false} 
 
       }, 
 
       _filter: function (applyFilter) 
 
          { 
 
          return function (item) 
 
          { 
 
           return !applyFilter || item.primary; 
 
          } 
 
          }, 
 
       _sort:  function (reverse) 
 
          { 
 
          return function (a, b) 
 
          { 
 
           if(reverse) 
 
           { 
 
           return a.id < b.id 
 
           } 
 
           return a.id >= b.id; 
 
          } 
 
          } 
 
      } 
 
     ); 
 
     } 
 
    ); 
 
    </script> 
 
    </dom-module> 
 

 
</head> 
 
<body> 
 
<test-app></test-app> 
 
</body> 
 
</html>

+0

データが正しく表示されません。 – tony19

+0

スニペットを実行してください。チェックボックスの組み合わせをクリックすると 'item content'と' x-item content'が一致するはずです –

+0

私はそれを実行しましたが、期待される結果が何であるかはあなたの質問ではっきりしません。 – tony19

答えて

0

、なぜならdom-repeatは、インスタンスを再利用する方法を、私はあなたが何をしようとして行うには良い方法はないと思います。

軽いDOMの子をx-item-testに渡すのではなく、プロパティバインディングを行うと、1.xでこれを行うのが最善の方法です。

各配列項目のインスタンスルックアップをO(n^2)とすると、一般的なケースでは許容できないと思います。

何かの理由で軽いDOMの子を本当に使用する必要がある場合、私が考えることができる最後の(恐ろしい)オプションは、テンプレートインスタンスを歩くdom-changeリスナを持つことです。

これは、プロパティのバインディングに優先する可能性のあるユースケースを想像することはできませんが、時には私はあまり想像力がありません。

私は2.0プレビューで、この問題を見ていないよ:

http://jsbin.com/vuritog/2/edit?html,output

お役に立てば幸いです。

+0

興味深い。 Chrome 56で2.0プレビューに問題が発生していないことが確認されましたが、まだChrome 53で発生しています(これは先にテストしたものです)。 – tony19

+0

ありがとうございます@DocDude、あなたのフィードバックに基づいて私たちのアプローチを考え直しています。私は、テキストノードの配布に関するコアの問題を作成しました。 –

関連する問題