ember.js - template - handlebars
EmberJS: compartir un controlador/plantilla para diferentes rutas (2)
Estuviste en lo correcto en todo momento.
Y también puede usar el nuevo controlador y plantilla en la edit route
.
Tienes que hacer solo dos cosas.
Primero, proporcione el nombre de la plantilla como nuevo en el renderTemplate
de la edit route
de edit route
.
App.LocationsEditRoute = Ember.Route.extend({
setupController: function(controller, model) {
this.controllerFor(''locations.new'').setProperties({isNew:false,content:model});
},
renderTemplate: function() {
this.render(''locations/new'')
}
});
A medida que se newController
la nueva plantilla, el controlador también será newController
, y puede tener la acción para apuntar a un evento en newController
.
Si desea cambiar el título y el texto del botón, puede tenerlos como propiedades calculadas observando la propiedad isNew
.
Espero que esto ayude.
PD: No te olvides de establecer la propiedad isNew en true en el setupController
de la new route
Tengo una aplicación CRUD muy simple que permite crear nuevos objetos y editarlos.
La plantilla utilizada para agregar un registro y editar un registro es casi idéntica.
Usan exactamente los mismos elementos de formulario. La única diferencia es el título y el botón debajo del formulario (que debe actualizar o crear un registro)
En mi implementación, tengo
- 2 definiciones de ruta
- 2 objetos de ruta
- 2 objetos de controlador
- 2 plantillas
Me preguntaba si
- No puedo promocionar la reutilización aquí
- si se requieren todos estos objetos
Lo que me molesta:
- Tengo 2 plantillas separadas para crear y editar (mientras que son casi idénticas)
- Tengo 2 controladores separados que hacen exactamente lo mismo.
Esperaba resolver esto en el nivel del controlador. Como un controlador decora un modelo, en mi caso, un solo objeto controlador podría envolver un nuevo registro o uno existente. Podría exponer una propiedad (isNewObject) para que la plantilla pueda decidir si estamos en el flujo "nuevo" o "editar". El controlador podría tener un único método createOrUpdate que funcione tanto en el escenario new
como en el de update
.
Rutas
La implementación actual está usando una ruta nueva y una ruta de edición para mi recurso.
this.resource("locations", function(){
this.route("new", {path:"/new"});
this.route("edit", {path: "/:location_id" });
});
La nueva ruta
La new route
es responsable de crear un nuevo registro y se llama cuando el usuario navega a la nueva pantalla de registro.
App.LocationsNewRoute = Ember.Route.extend({
model: function() {
return App.Location.createRecord();
}
});
La ruta de edición
La edit route
es responsable de editar un objeto existente cuando el usuario hace clic en el botón Editar en la pantalla de resumen. No he extendido la ruta de edición predeterminada, sino que estoy utilizando la que se generó automáticamente.
Controladores
Los controladores new
y de edit
son responsables de manejar la acción que ocurre en la plantilla (ya sea guardando o actualizando un registro)
Lo único que ambos controladores hacen es comprometer la transacción.
Nota: Supongo que este es un candidato para reutilización, pero ¿cómo puedo usar un único controlador para manejar 2 rutas / plantillas diferentes?
App.LocationsNewController = Ember.ObjectController.extend({
addItem: function(location) {
location.transaction.commit();
this.get("target").transitionTo("locations");
}
});
App.LocationsEditController = Ember.ObjectController.extend({
updateItem: function(location) {
location.transaction.commit();
this.get("target").transitionTo("locations");
}
});
Plantillas:
Como puede ver, el único reutilización de código que tengo aquí es el parcial (el enlace de campo del modelo). Todavía tengo 2 controladores (nuevos y de edición) y 2 plantillas.
Las nuevas plantillas establecen el título / botón correcto y reutilizan el formulario parcial.
<script type="text/x-handlebars" data-template-name="locations/new" >
<h1>New location</h1>
{{partial "locationForm"}}
<p><button {{action addItem this}}>Add record</button></p>
</script>
Las plantillas de edición establecen el título / botón correcto y vuelven a utilizar el parcial del formulario.
<script type="text/x-handlebars" data-template-name="locations/edit" >
<h1>Edit location</h1>
{{partial "locationForm"}}
<p><button {{action updateItem this}}>Update record</button></p>
</script>
El parcial
<script type="text/x-handlebars" data-template-name="_locationForm" >
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="latitude">Latitude</label>
<div class="controls">
{{view Ember.TextField valueBinding="latitude"}}
</div>
</div>
<div class="control-group">
<label class="control-label" for="latitude">Longitude</label>
<div class="controls">
{{view Ember.TextField valueBinding="longitude"}}
</div>
</div>
<div class="control-group">
<label class="control-label" for="accuracy">Accuracy</label>
<div class="controls">
{{view Ember.TextField valueBinding="accuracy"}}
</div>
</div>
</form>
</script>
Nota: Espero que pueda hacer algo eficiente / inteligente aquí.
Me gustaría que mi plantilla se viera así: (obtener el título del controlador y tener una sola acción que maneje tanto la actualización como la creación)
<script type="text/x-handlebars" data-template-name="locations" >
<h1>{{title}}</h1>
{{partial "locationForm"}}
<p><button {{action createOrUpdateItem this}}>Add record</button></p>
</script>
Pregunta
¿Puedo volver a trabajar este código para tener más reutilización de código, o es una mala idea intentar hacer esto con una única plantilla y un solo controlador para los flujos de "editar registro" y "nuevo registro". Si es así, cómo se puede hacer esto ? Me falta la parte donde mis 2 rutas (crear y editar) reutilizarían el mismo controlador / plantilla.
Utilizar esta:
App.YourNewRoute = Em.Route.extend ({
controllerName: ''controllerName'',
templateName: ''templateName''
});
Solo use el nombre inicial como para el usuario homeController "home", eso es todo.
Ejemplo:
App.YourNewRoute = Em.Route.extend ({
controllerName: ''home'',
templateName: ''home''
});
Ahora puede usar los métodos de plantilla y controlador de "inicio".