28

ナビゲーション サイドバーの「正しい方法」(または、これを行う単一の「Ember 方法」がない場合は、少なくともオプション) は何ですか? どうにかして ContainerViews を見るべきですか、それとも新しいアウトレット機能を使用してアプリケーション ビュー内にナビゲーションを固定するべきですか?

さらに、URL に応じて li に .active クラスを設定する「正しい方法」は何ですか (私はルーティングを使用しています)? これには何らかのヘルパーがありますか?

4

2 に答える 2

35

<更新日="2013-01-16">

Router API の最近の変更以降、前の例は無効になっているため、これらを修正するつもりはありません。古いルーターを使用しているすべてのアプリケーションは、できるだけ早く最新のものに移行する必要があります。

更新されたフィドルは次のとおりです 。 ライブデモ

私は頻繁に機能を維持/修正/追加します。

2013 年 4 月 3 日の編集:

代替サンプル - WIP:ソース| デモ

以下のすべてのコンテンツは非推奨です

<アップデート>

2012 年 11 月 9 日

特定のルートが選択されたときにOPが現在のナビゲーションバーアイテムにクラスを設定したい部分にも対処するより良いサンプルへのリンクを追加するだけです

JSFiddleのソース(ここをクリックし実行を確認してください)

NavigationController を見ると、'selected' プロパティが表示されます。これを使用して、子ビュー NavigationItemView の isActive メソッドをチェックインします。menuisActive は、同じビュー (テンプレートで定義) のプロパティの値とselected(コントローラーの)プロパティの値に基づいて、true または false を返します。次に、その特定の子のクラスに「アクティブ」または何も設定しない classNameBinding 式を確認します。また、そのナビゲーション項目を選択済みとしてマークしている ConnectOutlets も確認してください。

これはember-latestで実行されています。また、Ember.Bootstrapと、元の Twitter Bootstrap の機能/クラス/などの一部も使用しています (ただし、スタイルをmetro-bootstrapに置き換えました)。

スペースなどの関係で、ここにすべてを貼り付けることはできません。元のコードを残し、元の質問/回答を参照するために同じコードにリンクします。

ember が楽しいという理由だけで、この新しいサンプルを更新し続けます =)

</アップデート>

このフィドルは、ビューから静的なナビゲーション バーを表示します。アウトレットはコンテンツの表示にのみ使用されます。または、ディスプレイに直接移動して、実行されていることを確認できます。

ご覧のとおり、アクション リンクを含む単純なビューを使用して、このビューをアプリケーションのメイン ビューにレンダリングできます。「開始」の下のサブルートにも、同様のテンプレートに由来するミニ ナビゲーション バーがあります。

ハンドルバー:

<script type="text/x-handlebars" data-template-name="application">
    <h1>My Ember Application</h1>
    {{view App.NavbarView controllerBinding="controller.controllers.navbarController"}}
    <br /><hr />
    <div class="content">
        {{outlet}}
    </div>
</script>

<script type="text/x-handlebars" data-template-name="navbar">
    <ul>
        <li><a href="#" {{action gotoHome}}>Home</a></li>
        <li><a href="#" {{action gotoStarting}}>Getting Started</a></li>
        <li><a href="#" {{action gotoCommunity}}>Community</a></li>
    </ul>
</script>

<script type="text/x-handlebars" data-template-name="getting-started-menu">
    <ul>
        <li><a href="#" {{action gotoIndex}}>Overview</a></li>
        <li><a href="#" {{action gotoMVC}}>About MVC</a></li>
        <li><a href="#" {{action gotoEmber}}>About Ember</a></li>
    </ul>
</script>
    
<script type="text/x-handlebars" data-template-name="home">
    <h2>Welcome</h2>
    <br />
    <img src="http://emberjs.com/images/about/ember-productivity-sm.png" alt="ember logo" />
    <br />
    <br />
    <p>Bacon ipsum dolor sit amet qui ullamco exercitation, shankle beef sed bacon ground round kielbasa in. Prosciutto pig bresaola, qui meatloaf ea tongue non dolore et pork belly andouille ribeye spare ribs enim. Enim exercitation elit, brisket nisi ex swine in jerky consequat pastrami dolore sed ad. In drumstick cow, salami swine fatback short ribs ham ut in shankle consequat corned beef id. Deserunt prosciutto beef speck. Sirloin incididunt kielbasa excepteur irure.</p>
    <p>Do beef ribs dolore swine chicken shankle, venison officia qui magna ea anim. Jerky shank shankle, tongue in pork loin commodo boudin elit cupidatat turducken id capicola meatball. Strip steak ham hock tenderloin, id chicken drumstick sint jerky. Dolore veniam cillum minim, pariatur est beef. Sunt fatback tri-tip ex chuck.</p>
    <br />
    <br />
    <strong>Note</strong>: This is a basic template with no <i>bindings</i>
</script>

<script type="text/x-handlebars" data-template-name="starting">
    <h2>Getting Started with Ember</h2>
    {{view App.StartingMenuView}}
    <br />
    <br />
    <br />
    <p>Bacon ipsum dolor sit amet qui ullamco exercitation, shankle beef sed bacon ground round kielbasa in. Prosciutto pig bresaola, qui meatloaf ea tongue non dolore et pork belly andouille ribeye spare ribs enim. Enim exercitation elit, brisket nisi ex swine in jerky consequat pastrami dolore sed ad. In drumstick cow, salami swine fatback short ribs ham ut in shankle consequat corned beef id. Deserunt prosciutto beef speck. Sirloin incididunt kielbasa excepteur irure.</p>
    <p>Do beef ribs dolore swine chicken shankle, venison officia qui magna ea anim. Jerky shank shankle, tongue in pork loin commodo boudin elit cupidatat turducken id capicola meatball. Strip steak ham hock tenderloin, id chicken drumstick sint jerky. Dolore veniam cillum minim, pariatur est beef. Sunt fatback tri-tip ex chuck.</p>
    <br />
    <br />
    <strong>Note</strong>: This is a basic template has a menu view embedded
</script>

<script type="text/x-handlebars" data-template-name="about-mvc">
    <h2>About MVC</h2>
    {{view App.StartingMenuView}}
    <br /><br />
    <br /><p>
        Model–View–Controller (MVC) is a software design for interactive computer user interfaces that separates the representation of  information from the user's interaction with it.[1][8] The model consists of application data and business rules, and the controller mediates input, converting it to commands for the model or view.[3] A view can be any output representation of data, such as a chart or a diagram. Multiple views of the same data are possible, such as a pie chart for management and a tabular view for accountants.
    </p>
    Read more at <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" target="_blank">Wikipedia</a>
    <br />
    <br />
    <strong>Note</strong>: This is a basic template has a menu view embedded
</script>

<script type="text/x-handlebars" data-template-name="about-ember">
    <h2>About Ember</h2>
    {{view App.StartingMenuView}}
    <br /><br />
    <br />
    <p>A framework for creating <strong>ambitious</strong> web applications</p>
    Read more at <a href="http://emberjs.com/about/" target="_blank">emberjs.com</a>
    <br />
    <br />
    <p>Bacon ipsum dolor sit amet qui ullamco exercitation, shankle beef sed bacon ground round kielbasa in. Prosciutto pig bresaola, qui meatloaf ea tongue non dolore et pork belly andouille ribeye spare ribs enim. Enim exercitation elit, brisket nisi ex swine in jerky consequat pastrami dolore sed ad. In drumstick cow, salami swine fatback short ribs ham ut in shankle consequat corned beef id. Deserunt prosciutto beef speck. Sirloin incididunt kielbasa excepteur irure.</p>
    <p>Do beef ribs dolore swine chicken shankle, venison officia qui magna ea anim. Jerky shank shankle, tongue in pork loin commodo boudin elit cupidatat turducken id capicola meatball. Strip steak ham hock tenderloin, id chicken drumstick sint jerky. Dolore veniam cillum minim, pariatur est beef. Sunt fatback tri-tip ex chuck.</p><br />
    <br />
    <strong>Note</strong>: This is a basic template has a menu view embedded
</script>

<script type="text/x-handlebars" data-template-name="community">
    <h1>Ember Community</h1>
    <p>
        Get in touch with the community
    </p>
    <p>Featured contact info:</p>
    {{#each item in content}}
        <a {{bindAttr href="item.linkUrl" }} target="_blank">
            <img height="32" width="32" {{bindAttr src="item.imageUrl" title="item.displayName" alt="item.displayName"}} /><br />
            {{item.displayName}}
        </a><br />
    {{/each}}
    <br />
    Check more information about ember community at <a href="http://emberjs.com/community/" target="_blank">emberjs.com</a>
    <br />
    <br />
    <strong>Note</strong>: This is a template with a <i>foreach</i> type of loop
</script>​

JavaScript :

App = Em.Application.create();

App.ApplicationController = Em.Controller.extend();
App.ApplicationView = Em.View.extend({
    templateName: 'application'
});

App.HomeController = Em.Controller.extend();
App.HomeView = Em.View.extend({
    templateName: 'home'
});

App.NavbarController = Em.Controller.extend();
App.NavbarView = Em.View.extend({
    templateName: 'navbar'
});

App.StartingController = Em.Controller.extend();
App.StartingView = Em.View.extend({
    templateName: 'starting'
});


App.StartingMenuController = Em.Controller.extend();
App.StartingMenuView = Em.View.extend({
    templateName: 'getting-started-menu'
});

App.AboutMVCController = Em.Controller.extend();
App.AboutMVCView = Em.View.extend({
    templateName: 'about-mvc'
});

App.AboutEmberController = Em.Controller.extend();
App.AboutEmberView = Em.View.extend({
    templateName: 'about-ember'
});

App.CommunityModel = Em.Object.extend({
    displayName: null,
    linkUrl: null,
    imageUrl: null
});

App.CommunityController = Em.ArrayController.extend({
    content: [],
    init: function() {
        this._super();
        this.pushObject(
        App.CommunityModel.create({
            displayName: 'Twitter',
            linkUrl: 'https://twitter.com/#!/emberjs',
            imageUrl: 'http://icons.iconarchive.com/icons/iconshots/social-media-network/32/twitter-icon.png'
        }));
        this.pushObject(
        App.CommunityModel.create({
            displayName: 'GitHub',
            linkUrl: 'https://github.com/emberjs/ember.js',
            imageUrl: 'http://www.workinprogress.ca/wp-content/uploads/github.png'
        }));
    }
});

App.CommunityView = Em.View.extend({
    templateName: 'community',
    contentBinding: 'App.CommunityController.content'
});

App.Router = Em.Router.extend({
    enableLogging: true,
    location: 'hash',

    root: Em.Route.extend({
        // EVENTS
        gotoHome: Ember.Route.transitionTo('home'),
        gotoStarting: Ember.Route.transitionTo('starting.index'),
        gotoCommunity: Ember.Route.transitionTo('community.index'),

        // STATES
        home: Em.Route.extend({
            route: '/',
            connectOutlets: function(router, context) {
                router.get('applicationController').connectOutlet('home');
            }
        }),
        starting: Em.Route.extend({
            // SETUP
            route: '/starting',
            connectOutlets: function(router, context) {
                router.get('applicationController').connectOutlet('starting');
            },
            // EVENTS
            gotoMVC: Ember.Route.transitionTo('mvc'),
            gotoEmber: Ember.Route.transitionTo('ember'),
            gotoIndex: Ember.Route.transitionTo('index'),

            // STATES
            index: Em.Route.extend({
                route: '/',
                connectOutlets: function(router, context) {
                    router.get('applicationController').connectOutlet('starting');
                }
            }),
            mvc: Em.Route.extend({
                route: '/mvc',
                connectOutlets: function(router, context) {
                    router.get('applicationController').connectOutlet('aboutMVC');
                }
            }),
            ember: Em.Route.extend({
                route: '/ember',
                connectOutlets: function(router, context) {
                    router.get('applicationController').connectOutlet('aboutEmber');
                }
            })
        }),
        community: Em.Route.extend({
            // SETUP
            route: '/community',
            connectOutlets: function(router, context) {
                router.get('applicationController').connectOutlet('community');
            },
            // EVENTS
            // STATES
            index: Em.Route.extend({
                route: '/',
                connectOutlets: function(router, context) {
                    router.get('applicationController').connectOutlet('community');
                }
            })
        })
    })
});
App.initialize();​
于 2012-07-03T21:41:17.797 に答える
8

私はMilkyWayJoeの答えが好きではありませんでした.遅かれ早かれ状態の命名を変更したい場合や、コードとビューを通過しなければならないものを変更したい場合、すべてのルートにtransitionTo関数を追加することも望ましくないようです. 私のアプローチは、もう少しプログラム的でモジュール化されています。

# Parent View-Tamplate, holding the navbar DOM elements
App.NavView = Ember.View.extend( 
  controller: App.NavArrayController
  templateName: "ember-nav"
)
# We push NavItems into this array
App.NavArrayController = Ember.ArrayController.create(
  content: Ember.A([])
)
# NavItem has two settable properties and 
# an programmatic active state depending on the router
App.NavItem = Ember.Object.extend(
  title: ''
  goto: null    # <=this is the name of the state we want to go to!
  active: (->
    if App.router.currentState.name == @.get "goto"
      true
    else
      false
  ).property('App.router.currentState.name').cacheable()
)
# the actual NavElement which gets the class="active" if the 
# property "active" is true, plus a on-click binding to
# make the Router transition to this state
App.NavItemView = Ember.View.extend(
 tagName: "li"
  classNameBindings: ["active"]
  click: ->
    App.router.transitionTo(@get('goto'))
    false
)

nav-view.hbs (twitter-bootstrap-style nav 用)

<div class="nav-collapse collapse">
  <ul class="nav">
    {{#each App.NavArrayController}}
      {{#view App.NavItemView classBinding="active" gotoBinding="goto"}}
        <a href="#" {{bindAttr data-goto="goto"}}> {{title}}</a>
      {{/view}}
    {{/each}}
  </ul>
</div>

このようにして、ルーターでルートを作成していじり、Nav-Definitions を並べて保持することができます。

# put this somewhere close to the Router 
App.NavArrayController.pushObjects(
  [
    App.NavItem.create(
      title: 'Home'
      goto: 'home'
    ),
    App.NavItem.create(
      title: 'Chat'
      goto: 'chat'
    ),
    App.NavItem.create(
      title: 'Test'
      goto: 'test'
    )
  ]
)
于 2012-12-27T16:03:01.930 に答える