Ember.js y manillares cada ayudante, con subvistas
-
12-12-2019 - |
Pregunta
Estoy intentando usar el asistente de vista dentro de mis bloques de plantilla {{#each}} sin usar rutas globales (mis controladores crean y destruyen sus propias vistas).
Ejemplos.Dada una vista con una propiedad de matriz myList y una vista secundaria itemButton:
esto funcionará
<script type="text/x-handlebars" name="my-list-view">
{{#each myList}} <!-- App.myListView.myList -->
{{view App.myListView.itemButton}} {{title}}
{{/each}}
</script>
Esto no:
<script type="text/x-handlebars" name="my-list-view">
{{itemButton}} <!-- works fine outside the each -->
{{#each myList}}
{{view itemButton}} {{title}} <!-- itemButton view not found -->
{{/each}}
</script>
Parece que no puedo acceder a la vista principal desde cada ayudante de vista (o, de hecho, acceder a cualquier otra cosa que no sean las propiedades de los objetos que se están iterando).
Las soluciones hacky Se me ocurrieron son:
- Agregue la vista que quiero usar a los elementos sobre los que estoy iterando.
o
- Creando una vista de colección en App.myListView
- Cree una vista itemViewClass en esa clase de vista de colección
- Mueva la vista itemButton dentro de itemViewClass
- Reemplace {{#each}} con {{#collection}}
o
- Cree un asistente de manillar personalizado para la iteración.
Ambas opciones parecen horribles.Sin embargo, seguramente hay una mejor alternativa que crear 2 clases nuevas (y anidar 4 vistas de profundidad) solo para iterar sobre una lista.¿Existe algún asistente de manillar de repuesto que pueda utilizar en su lugar?
Implementaciones de soluciones alternativas
Opción 1 :Modificar la matriz de contenido
http://jsfiddle.net/FQEZq/3/Desventajas:Tener que agregar la vista a cada instancia del modelo solo para la iteración.
Opcion 2 :Vista de colección personalizada
http://jsfiddle.net/ST24Y/1/Desventajas:Ahora tiene dos vistas adicionales que no necesita ni desea y menos control del marcado.Las referencias de la vista secundaria a la instancia principal ahora requieren parentView.parentView.parentView.
Solución
#each
es demasiado limitado para sus necesidades.Puede hacerlo funcionar si está dispuesto a utilizar una ruta global a la vista que desea anidar dentro del #each
.De lo contrario, su enfoque de vista de colección es el mejor.Es probable que agregar la vista a la instancia del modelo enturbie el diseño de su aplicación, por lo que lo evitaría.
Una idea para mantener limpias tus plantillas es aprovechar Ember.View
propiedades como:
collectionView
- Devuelve el ancestro más cercano que sea unEmber.CollectionView
itemView
- Devuelve el antepasado más cercano que es hijo directo de unEmber.CollectionView
contentView
- Devuelve el antepasado más cercano que tiene el contenido de la propiedad.
Otros consejos
La gran cosa aquí - Opciones.
Los ganchos de cómo desea usar una plantilla están disponibles.Estos son:
<-- render templates/name.js -->
{{partial 'name'}}
<-- render views/name.js -->
{{view 'name'}}
<-- render views/name1.js with controllers/name2.js -->
{{render 'name1' 'name2'}}
<!-- see also: -->
{{output}}
{{output 'named'}}
{{yield}}
Una variante de ejemplo de su plantilla inicial que muestra 4 opciones diferentes:
<script type='text/x-handlebars' data-template-name='my-list-view'>
<h2>Option 1</h2>
{{#each myList}}
{{! the 2nd parameter will look for itemButtonController }}
{{render 'itembutton' itemButton}}
{{/each}}
<h2>Option 2</h2>
{{#each myList}}
{{! using an Ember Component }}
{{#item-button }}
some static text OR {{dynamic}}
{{/item-button}}
<!-- in component/item-button.hbs add {{yield}} for where you want the static content to output -->
{{/each}}
<h2>Option 3</h2>
{{#each myList}}
{{! if the button is to be a link }}
{{#link-to 'route' parameter tagName='button' classNames='btn'}}
{{title}}
{{/link-to}}
{{/each}}
<h2>Option 4</h2>
<p>Ludicrous example showing almost every reference option!</p>
{{! focus the context on subview data }}
{{#with someArrayOrCollectionOfView}}
{{! prepend type to add context - here returning back up to this view's properties }}
{{#each view.myList}}
{{! this is equivalent to someArrayOrCollectionOfView[x].name }}
{{name}}
{{! a button that hooks in route, model, and 2 controllers, and applies a target for the output when clicked }}
{{#link-to 'page' controllers.page.nextPage target='outlet' tagName='button' disabledWhen=controller.disableNext }}
{{model.buttonName}}
{{/link-to}}
{{/each}}
{{/with}}
{{! generic default target (automatic) }}
{{outlet}}
{{! example of a named target }}
{{outlet 'footerlinks'}}
</script>
MMMM ... Referencia para leer más: Ember.HandleBars.Helpers