desplazamiento infinito con ember.js(carga diferida)
lazy-loading infinite-scroll (4)
¿Conocía el nuevo componente Ember.ListView lanzado?
https://github.com/emberjs/list-view
Fue anunciado en el San Francisco Ember Meetup de febrero. Aquí hay una plataforma deslizante de Erik Bryn, uno de los desarrolladores de Ember Core sobre su uso:
Tengo una vista donde puede haber una gran cantidad de elementos para que el usuario se desplace y me gustaría implementar el desplazamiento infinito para permitir la carga progresiva del contenido.
Parece que algunas personas han hecho paginación, pero Google no menciona a nadie que haya discutido cómo han hecho infinitas listas con Ember / Ember Data. ¿Alguien ya ha trabajado en esto y tiene una publicación de blog / código de ejemplo para compartir?
Estoy escribiendo un plugin de paginación infinita para Ember basado en el trabajo de @ pangratz.
Por favor, abra cualquier problema allí si tiene preguntas o mejoras que le gustaría.
Implementé un mecanismo de desplazamiento infinito en el project GitHub Dashboard
, actualmente estoy desarrollando. La función se agrega en commit 68d1728 .
La idea básica es tener un LoadMoreView
que invoque el método loadMore
en el controlador cada vez que la vista esté visible en la ventana loadMore
actual. Estoy usando el plugin jQuery para esto. Le permite registrarse para un evento de inview
, que se activa cuando el elemento del selector especificado es visible en la pantalla y cuando desaparece.
El controlador también tiene propiedades que indican si hay más elementos para cargar y si actualmente hay elementos recuperados. Estas propiedades se llaman canLoadMore
y isLoading
.
El LoadMoreView
básicamente se ve así:
App.LoadMoreView = Ember.View.extend({
templateName: ''loadMore'',
didInsertElement: function() {
var view = this;
this.$().bind(''inview'', function(event, isInView, visiblePartX, visiblePartY) {
if (isInView) Ember.tryInvoke(view.get(''controller''), ''loadMore'');
});
}
});
donde la plantilla loadMore
se define de la siguiente manera:
{{#if isLoading}}
fetching some more stuff <img width="10" src="img/ajax-loader.gif" >
{{else}}
{{#if canLoadMore}}
<a {{action "loadMore" target="controller" }}>click to load more items</a>
{{else}}
<i>no more items</i>
{{/if}}
{{/if}}
El controlador que maneja la obtención de más elementos se implementa de la siguiente manera. Tenga en cuenta que en el método loadMore
se realiza una consulta en la tienda, que carga una página específica de entradas para un modelo.
App.EventsController = Ember.ArrayController.extend({
currentPage: 1,
canLoadMore: function() {
// can we load more entries? In this example only 10 pages are possible to fetch ...
return this.get(''currentPage'') < 10;
}.property(''currentPage''),
loadMore: function() {
if (this.get(''canLoadMore'')) {
this.set(''isLoading'', true);
var page = this.incrementProperty(''currentPage'');
// findQuery triggers somehing like /events?page=6 and this
// will load more models of type App.Event into the store
this.get(''store'').findQuery(App.Event, { page: page });
} else {
this.set(''isLoading'', false);
}
}
});
Lo único que queda es configurar inicialmente el content
del controlador para el resultado de una función de filter
, por lo que el content
se actualiza cuando se cargan nuevos modelos en la tienda (lo que sucede debido al método findQuery
en loadMore
del controlador). Además, se agrega un hash de query
cuando se invoca el filter
. Esto asegura que se realice una consulta inicial al servidor.
App.eventsController = App.EventsController.create({
content: []
});
var events = App.store.filter(App.Event, { page: 1 }, function(data) {
// show all events; return false if a specific model - for example a specific
// type of event - shall not be included
return true;
});
Yo recomendaría usar el complemento Ember Infinity . Es compatible con Ember 1.10 hasta 2.0+. Es relativamente fácil de configurar. Solo necesita modificar su ruta y plantilla.
Ruta ( Product
es modelo de ejemplo):
import InfinityRoute from ''ember-infinity/mixins/route'';
export default Ember.Route.extend(InfinityRoute, {
model() {
/* Load pages of the Product Model, starting from page 1, in groups of 12. */
return this.infinityModel(''product'', { perPage: 12, startingPage: 1 });
}
});
Modelo:
{{#each model as |product|}}
...
{{/each}}
{{infinity-loader infinityModel=model}}
Cuando el componente {{infinity-loader}}
vuelve visible, envía una acción a su ruta, por lo que sabe actualizar la matriz del modelo con los registros nuevos (recuperados).
La primera solicitud será enviada a:
/products?per_page=12&page=1
Por lo tanto, también debe preparar su API back-end para manejar estos parámetros de consulta. Obviamente es personalizable, eche un vistazo a la sección Uso avanzado del archivo Léame .
Nota :
Tanto el uso de ListView
(respuesta de @commadelimited) como las vistas con ArrayController
(respuesta de @ pangratz) se desaprobaron o eliminaron a partir de la versión estable de Ember 2.0.