2012-07-03 4 views
28

ナビゲーションサイドバーの "正しい方法"(またはこれを実行する単一の "Ember方法"がない場合、少なくともオプション)とは何ですか?私は何とかContainerViewsを見ているべきでしょうか、あるいは私はちょうど新しいコンセント機能を使用して、アプリケーションビューの中にナビゲーションを張っておくべきですか?正しい方法Emberでナビゲーションを実行する

さらに、URLに応じてliに.activeクラスを設定する "正しい方法"(私はルーティングを使用しています)は何ですか?これのための助けのいくつかの種類ですか?

答えて

35

<更新日時=「2013年1月16日」>

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

ここに更新されたフィドルです: Source | Live Demo

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

編集2013

代替サンプル - WIP:source | demo

以下のすべてのコンテンツは推奨されていません

<更新>

2012 - 11月 - 09だけでも、OPがしたい部分に対処し、より良いサンプルへのリンクを追加

指定されたルートが選択されたときに現在のナビゲーションバー項目にクラスを設定する

ソースJSFiddlehereをクリックすると表示されます)

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

これはember-latestで実行されています。 また、Ember.Bootstrapと、オリジナルのTwitter Bootstrapの機能/クラス/ etc(ただし、スタイルをmetro-bootstrapに置き換えました)の少しを使用しています。

スペースとすべてのためにここにすべてを貼り付けません。元の質問/回答を参照するために、元のコードとリンクをそのまま残します。

私はエンバーは楽しみであるという理由だけで、この新しいサンプルを更新しておこう

=)

< /更新>は

This fiddleビューから静的ナビゲーションバーを示しており、コンセントにのみ使用されますコンテンツを表示するには直接see it running

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

ハンドル

<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();​ 
+6

私よりはるかに高速です。 IMHOこの例は、emberサイトの例の一部でなければなりません。 –

+1

私はサンプルを書いていますので、すでにいくつかのテンプレートがありました。私は後でCSSクラスの部分を応えるためにフィドルを変更するかもしれません – MilkyWayJoe

+4

素敵な、ありがとう!私はこれがEmberサイトにあるはずであることに同意します。私はEmberのドキュメントが実際にはかなり欠けていることを発見しました。サイトのドキュメンテーションは私に多くの質問を残しました。主に単一のビューだけでなく、実際のアプリケーションのためのすべての方法をまとめました。 1.0日後に私が学んだRailsでは、スクリーンキャストは素晴らしい出発点でした。私はEmberがそういうものを持っていたらいいのに。 – user1499207

8

あなたは遅かれ早かれ、あなたの状態や何でもあなたの命名を変更したい場合ので、私はMilkyWayJoeの答えを好きではなかったですコードを通り抜けなければならず、ビューも同様に、すべてのルートにtransitionToへの関数を追加することは望ましくないように見える。 私のアプローチは、もう少し、プログラムやモジュール化である:(TwitterのブートストラップスタイルのNAV用)

# 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

<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> 

この方法で、私はちょうどで周りを作成し、混乱することができますルータ内の私のルートは で、ナビ定義は横に並べておいてください。

# 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' 
    ) 
    ] 
) 
+0

これは、リンクが実際にリンクでありアクションではないという利点があります。つまり、hrefがあり、「新しいタブで開く」などのブラウザアクションが機能します。 '' href = "#" 'を' href = "/#/ {{unbound goto}}" '' – Ginty

+1

私は皆さんに同意します。私はコードの更新版で取り組もうとしましたが、私が望むところにはあまり行きませんでした。新しいルータがアップしたので、(ある時点で)私はこれをアップデートして、この実装をより一層整えるようにします。 P – Thomas

+1

に設定した場合のみ、 – MilkyWayJoe

関連する問題