ember.js - transitiontoroute - outlet ember
Forma correcta de hacer navegación con Ember (2)
¿Cuál es la "manera correcta" (o al menos las opciones, si no hay una sola "forma Ember" de hacer esto) para una barra lateral de navegación? ¿Debo estar mirando ContainerViews de alguna manera, o debería simplemente usar la nueva característica de salida y pegar la navegación dentro de mi vista de aplicación?
Además, ¿cuál es la "manera correcta" de establecer una clase .active en un li dependiendo de la URL (estoy usando el enrutamiento)? ¿Hay algún tipo de ayuda para esto?
No me gustó la respuesta de MilkyWayJoe porque si tarde o temprano quiere cambiar el nombre de sus estados o lo que sea que tenga que pasar por el código Y la vista también, agregar una función a transitionTo cada ruta parece no deseable. Mi enfoque es un poco más programático y modular:
# 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 (para nav-twitter-bootstrap-style)
<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>
De esta forma, puedo crear y jugar con mis rutas en el Enrutador y mantener las Definiciones de navegación una al lado de la otra:
# 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''
)
]
)
<Fecha de actualización = "2013-01-16">
Los ejemplos anteriores ya no son válidos desde los cambios recientes en la API del enrutador, así que no voy a solucionarlos. Todas las aplicaciones que usan el enrutador anterior deben migrar lo más pronto posible a la última.
Aquí hay un violín actualizado: Source | Demo en vivo
Voy a mantener / corregir / agregar características de vez en cuando.
Editar el 3 de abril de 2013 :
Muestra alternativa - WIP: source | demo
TODO EL CONTENIDO DE ABAJO ESTÁ DEPRECADO
<Actualización>
2012-Nov-09
Solo agregue un enlace a una muestra mejor que también aborde la parte que el OP desea establecer una clase en el elemento actual de la barra de navegación cuando se selecciona una ruta determinada
Fuente en JSFiddle (Haga clic here para verla ejecutándose)
Si miras en NavigationController, verás la propiedad ''selected'', que utilizo para verificar el método isActive de la vista secundaria NavigationItemView. El isActive devolverá verdadero o falso basado en el valor en la propiedad del menu
de la misma vista (definida en la plantilla) y el valor en la propiedad selected
(del controlador). Luego, compruebe las expresiones classNameBinding que establecen ''active'' o nothing a la clase de ese niño en particular. También verifique los ConnectOutlets que es donde estoy marcando ese elemento de navegación como seleccionado.
Esto se está ejecutando el ember-latest . También estoy usando un poco de Ember.Bootstrap , así como algunas de las funciones / clases / etc originales de Twitter Bootstrap (pero he reemplazado los estilos con metro-bootstrap ).
No pegar todo aquí debido al espacio y todo. Dejaré el código original y el enlace al mismo para referencia a la pregunta / respuesta original.
Voy a seguir actualizando esta nueva muestra solo porque la brasa es divertida =)
</ Update>
Este violín muestra una barra de navegación estática desde una vista, y la salida se usa solo para mostrar el contenido, o puede ir directamente a la pantalla para verlo funcionando
Como puede ver, puede usar una vista simple que contenga sus enlaces de acción y hacer que esta vista se represente en su vista principal de la aplicación. Las rutas secundarias bajo "inicio" también tienen una mini barra de navegación, proveniente de una plantilla similar.
Manubrios :
<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();