0

次のようなコレクション ビューがあります (CoffeeScript):

App.SearchSuggestionsList = Ember.CollectionView.extend
  tagName: 'ul'
  contentBinding: 'controller.controllers.searchSuggestionsController.content'
  itemViewClass: Ember.View.extend
    template: Ember.Handlebars.compile('{{view.content.title}}')
    isSelected: (->
      /* This is where I don't know what to do */
      this.index == controller's selected index 
    ).property('controller.controllers.searchSuggestionsController.selectedIndex')
  emptyView: Ember.View.extend
    template: Ember.Handlerbars.compile('<em>No results</em>')

ご覧のとおり、 isSelected メソッド内にいくつかの疑似コードがあります。私の目標は、このまだ実装されていない isSelected プロパティを介して、現在選択されている項目の概念を定義することです。これにより、現在選択されている項目に条件付きの className を適用できます。

これは行く方法ですか?そうである場合、この isSelected メソッドをどのように実装できますか? そうでない場合、同じことを達成するための別の方法は何ですか?

4

2 に答える 2

1

リストを変更することで、あなたが探しているケースを解決できると思います。

上記のソリューションと似ていますが、選択されたフラグは、選択されたフラグではなく、コレクションのコントローラーに基づいています。これにより、itemControllerの内容のみが考慮されるため、クリック、URL、キー押下などを介して「選択された」部分を変更できます。

したがって、SearchListControllerはアイテムとアイテムコントローラーを参照します(ルーターでconnectControllerを呼び出すことを忘れないでください)

App.SearchListController = Em.ObjectController.extend
  itemsController: null
  itemController: null

App.SearchListView = Em.View.extend
  templateName: "templates/search_list"

個々のアイテムには独自のビューが必要です。それらのコンテキスト(アイテム)がitemControllerのアイテムと一致する場合、それらはクラスとして追加されて選択されます。

App.SearchListItemView = Em.View.extend
  classNameBindings: ['selected']
  tagName: 'li'
  template: Ember.Handlebars.compile('<a {{action showItem this href="true" }}>{{name}}</a>')
  selected:(->
    true if @get('context.id') is @get('controller.itemController.id')
  ).property('controller.itemController.id')

次に、SearchListテンプレートは、itemsController内のすべてのアイテムをループし、それらが単一アイテムビューのコンテキストになるためです。

<ul>
  {{each itemsController itemViewClass="App.SearchListItemView"}}
</ul>

それはあなたが探しているものに近いですか?

于 2012-11-21T18:15:51.410 に答える
0

これを行うための簡単な (または最もよく知られている) 方法は、子ビュー (navbar アイテム) に、コントローラーにバインドされている親ビュー (navbar) の「選択された」プロパティを観察させることです。したがって、ルートでコントローラーに伝えます。どの項目が選択されています。このフィドル全体を確認してください。

例:

ナビゲーションバーのハンドルバー テンプレート

<script type="text/x-handlebars" data-template-name="navbar">
    <ul class="nav nav-list">
        <li class="nav-header">MENU</li>
        {{#each item in controller}}            
            {{#view view.NavItemView 
                    itemBinding="item"}}
                <a {{action goto item target="view"}}>
                    <i {{bindAttr class="item.className"}}></i>
                    {{item.displayText}}
                </a>
            {{/view}}
        {{/each}}
    </ul>    
</script>

navbar コントローラーには、ビューでもバインドする「選択された」プロパティが必要です

App.NavbarController = Em.ArrayController.extend({
    content: [
        App.NavModel.create({
            displayText: 'Home',
            className: 'icon-home',
            routeName: 'home',
            routePath: 'root.index.index'
        }),
        App.NavModel.create({
            displayText: 'Tasks',
            className: 'icon-list',
            routeName: 'tasks',
            routePath: 'root.index.tasks'
        })
    ], 
    selected: 'home'
});

次に、これに似たビュー構造があり、子ビューは、「選択された」親ビューが子と同じ名前を持っているかどうかを確認します

App.NavbarView = Em.View.extend({
    controllerBinding: 'controller.controllers.navbarController',
    selectedBinding: 'controller.selected',
    templateName: 'navbar',
    NavItemView: Em.View.extend({
        tagName: 'li',
        // this will add the "active" css class to this particular child
        // view based on the result of "isActive"
        classNameBindings: 'isActive:active',
        isActive: function() {
            // the "routeName" comes from the nav item model, which I'm filling the 
            // controller's content with. The "item" is being bound through the
            // handlebars template above
            return this.get('item.routeName') === this.get('parentView.selected');
        }.property('item', 'parentView.selected'),
        goto: function(e) {
            App.router.transitionTo(this.get('item.routePath'), e.context.get('routeName'));
        }
    })
});

次に、次のようにルートに設定します。

App.Router = Em.Router.extend({
    enableLogging: true,
    location: 'hash',
    root: Em.Route.extend({
        index: Em.Route.extend({
            route: '/',
            connectOutlets: function(r, c) {
                r.get('applicationController').connectOutlet('navbar', 'navbar');
            },
            index: Em.Route.extend({
                route: '/',
                connectOutlets: function (r, c) {
                    // Here I tell my navigation controller which 
                    // item is selected
                    r.set('navbarController.selected', 'home');

                    r.get('applicationController').connectOutlet('home');
                }
            }),
            // other routes....
        })
    })
})

お役に立てれば

于 2012-11-20T22:31:04.093 に答える