1

この質問のフィドルは次のとおりです(コンソールが開いていることを確認してください):

基本的に、ハンドルバー ブロック ビューを親として持ち、アイテムの配列をループして、アイテムごとに子ブロック ビューを作成します。後で、それらの子がなんらかの方法で変更されるので、そのイベントを検出して処理したいと考えています。

要約コード:

{{#view App.outerView}}
    {{#each item in items}}
        <h6>Person:</h6>
        {{#view App.innerView}}
            <dl>
                <dt>First Name</dt><dd>{{item.first}}</dd>
                <dt>Last Name</dt><dd>{{item.last}}</dd>
            </dl>
        {{/view}}
    {{/each}}
{{/view}}

後の時点で:

controller.get( 'items' ).pushObject( 'new item' );

jsFiddle では、最後の子オブジェクトを常に強調表示したまま (アクティブ = true) にしようとしています。outerView が最初に挿入されると、強調表示が最後の項目に適用され、期待どおりに機能します。後で新しいアイテムを追加すると、ハイライト メソッドが起動しますが、新しいアイテムは表示されません。

これに関する 2 つの質問:

  • 主な質問: 最後のアイテム (マット) が強調表示されないのはなぜですか? 言い換えれば、新しい項目が追加された後childViews.lengthも古い値が報告されるのはなぜでしょうか? これを行うためのより良い方法はありますか?

  • 二次的な質問childViews:新しいアイテムを追加すると、オブザーバーが 2 回発火するのはなぜですか? (合計 3 回: 最初の挿入で 1 回、新しい子項目の追加で 2 回)


編集:私のニーズをよりよく説明するために、フィドルを少し調整しました。outerView の混合コンテンツ (HTML + innerViews) に注意してください。基本的に、outerView は、ビュー/データの配列/コレクションだけでなく、すべてのコンテンツを子として受け入れる必要があります。

編集 2 : さらなる明確化: 事後にこれらの子ビューを操作することは別の話であり、childViews(ember ビュー) のコンテンツを操作するか、jQuery を使用して正式な ember ビュー オブジェクトではない可能性のある HTML 要素を操作することによって達成できます。他の手段。ここでの本当の目的は、outerView コンテンツのいずれかが変更されたときに (childView の現在のコピーを使用して) イベントをキャプチャすることです。

編集 3 : ここに Github の問題があります

4

2 に答える 2

1

最初のコードが少し複雑に見えます。同じ結果を達成するためのより良い方法を次に示します。

http://jsfiddle.net/XaN8T/1/

{{each}}各項目をコントローラーでラップする必要があります。これはヘルパーで簡単に実行できます。

<script data-template-name="application" type="text/x-handlebars">
    This is a list:
    <ul>
        {{each controller itemController="item" itemViewClass="App.ItemView"}}
    </ul>
</script>

アイテム用に別のテンプレートを作成します。

<script data-template-name="item" type="text/x-handlebars">
    <h6>Person:</h6>
    <div {{bindAttr class=":content active"}}>
        <dl>
            <dt>First Name</dt><dd>{{first}}</dd>
            <dt>Last Name</dt><dd>{{last}}</dd>
        </dl>
    </div>
</script>

needs次に、次のプロパティを使用して、Ember で計算されたプロパティを利用できactiveます。

App.ItemController = Ember.ObjectController.extend({
    needs: ['application'], //This way each ItemController can access the ApplicationController's content (i.e. the list of all items)
    active: function() {
        return this.get('controllers.application.lastObject') === this.get('content');
    }.property('controllers.application.lastObject')
});

次にApp.ItemView、その css クラスをコントローラーのactiveプロパティにバインドします。

App.ItemView = Ember.View.extend({
    tagName: 'li',
    templateName: 'item',
    classNameBindings: ['controller.active']
});

出来上がり!できます :)

于 2013-03-27T19:32:32.480 に答える
0

フィドルで達成したことを行うより良い方法は、Ember.CollectionViewを使用することです。

itemViewClass次に、子がactiveクラスの最後の子であるかどうかを決定する計算されたプロパティを追加します

active: function () {
  return this.get("elementId") === this.get("parentView.childViews.lastObject.elementId");
}.property('parentView.childViews.length'),

ここに ワーキングフィドルがあります

ビューのコレクションを処理する必要がある場合はいつでも、必要に応じてCollectionViewEmber.ContainerView (これにより、子ビューの操作をより詳細に制御できます) を使用できますが、ほとんどの場合Ember.CollectionViewは十分です。

于 2013-03-14T07:35:44.487 に答える