1

template.renderを使用してhtmlテンプレートに基づいてアイテムの配列をレンダリングしているという問題があります。配列内の各アイテムには、領域の親要素内に、別のテンプレートにバインドする別の配列も含まれています。グループにグリッドレイアウトを使用できることはわかっていますが、これを別の方法で実現しようとしているので、別のコントロールを使用することを提案しないでください。以下が正しく機能しない理由について知りたいだけです。

   //html templates
   <div id="area-template" data-win-control="WinJS.Binding.Template">
    <h1 class="area-title" data-win-bind="innerHTML:title"></h1>
    <div class="items">

    </div>
  </div>

<div id="item-template" data-win-control="WinJS.Binding.Template">
    <h2 class="item-title" data-win-bind="innerHTML:title"></h2>
</div>

   // JS in ready event
   var renderer = document.getElementsByTagName('section')[0];
            var area_template = document.getElementById('area-template').winControl;
            var item_template = document.getElementById('item-template').winControl;
            for (var i = 0; i < areas.length; i++) {
                var area = areas.getAt(i);
                area_template.render(area, renderer).done(function (el) {
                    var item_renderer = el.querySelector('.items');
                    for (var j = 0; j < area.items.length; j++) {
                        var item = area.items[j];
                        item_template.render(item, item_renderer).done(function (item_el) {
                        });
                    }
                });
            }

つまり、領域をレンダリングした後、「done」関数で新しく作成された要素(el)が返され、アイテムを追加するのは「.items」divであることがわかります。ただし、これにより、作成された最初のdivにすべてのアイテムが追加されます。それが最後のdivだった場合、クロージャのためにもっと理にかなっているかもしれませんが、最初のdivで発生するという事実は、本当に私を失望させています!

興味深いのは、document.createElementとel.appendChildを使用してテンプレートレンダリング関数を置き換えると、正しく表示されることです。例:(領域レンダリングの完了)

 area_template.render(area, renderer).done(function (el) {
    var item = area.items[j];
    var h2 = document.createElement('h2');
    h2.innerText = item.title;
    el.appendChild(h2);
}

これはelであることに気づきましたが、elの実際の.items divではなく、追加しています。

ここで何が起こっているのかよくわかりません。elの値は正しく更新されているようですが、el.querySelectorは常に間違った「.items」divを返すか、どこかに保持されていますが、デバッグでは、ループ中にelが変更されていることが示されます。任意の洞察をいただければ幸いです。

ありがとう

4

1 に答える 1

1

私はここで何が起こっているのかを理解しました。レンダリングプロミスで返される「el」は、私が思ったように新しく作成された要素ではありません。これは、レンダラーと新しく作成されたhtmlを一緒にしたものです。したがって、el.querySelector('。items')は、常に最初に見つかった'.items'を返します。ドキュメントを読み間違えたに違いありませんが、同じエラーが発生した場合に備えて、他の誰かがこの情報を役立つことを願っています。

これを回避する1つの方法は、item_rendered = el.querySelectorAll('。items')[i]を実行し、ループ内の位置に基づいて番号が付けられた'.items'を返すことだと思います。

例えば

   for (var i = 0; i < areas.length; i++) {
                var area = areas.getAt(i);
                area_template.render(area, renderer).done(function (el) {
                    var item_renderer = el.querySelectorAll('.items')[i];
                    for (var j = 0; j < area.items.length; j++) {
                        var item = area.items[j];
                        var h2 = document.createElement('h2');
                        h2.innerText = item.title;
                        item_renderer.appendChild(h2);
                    }
                });
            }
于 2012-11-24T20:27:39.277 に答える