oneindig scrollen met ember.js (lui laden)

Ik heb een weergave waar de gebruiker door een groot aantal items kan scrollen en ik zou oneindig scrollen willen implementeren om progressief laden van de inhoud mogelijk te maken.

Het lijkt erop dat sommige mensen hebben gepagineerdmaar Google brengt niemand ter sprake die bespreekt hoe ze oneindige lijsten hebben gemaakt met Ember/Ember Data. Heeft iemand hier al mee gewerkt en een blogpost/voorbeeldcode om te delen?


Antwoord 1, autoriteit 100%

Ik heb een oneindig scrollmechanisme geïmplementeerd in het GitHub Dashboardproject, ik ben momenteel in ontwikkeling. De functie is toegevoegd in commit 68d1728.

Het basisidee is om een ​​LoadMoreViewte hebben die de loadMoremethode op de controller aanroept telkens wanneer de weergave zichtbaar is op de huidige viewport. Ik gebruik hiervoor de jQuery-plug-in inview. Hiermee kunt u zich registreren voor een inview-gebeurtenis, die wordt geactiveerd wanneer het element van de opgegeven selector zichtbaar is op het scherm en wanneer het verdwijnt.

De controller heeft ook eigenschappen die aangeven of er meer items moeten worden geladen en of er momenteel items zijn opgehaald. Deze eigenschappen worden canLoadMoreen isLoadinggenoemd.

De LoadMoreViewziet er in principe als volgt uit:

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');
    });
  }
});

waar de sjabloon loadMoreals volgt is gedefinieerd:

{{#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}}

De controller die het ophalen van meer items afhandelt, wordt dan als volgt geïmplementeerd. Merk op dat in de loadMore-methode een query op de winkel wordt uitgevoerd, die een specifieke pagina met items voor een model laadt.

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);
    }
  }
});

Het enige dat overblijft is om in eerste instantie de contentvan de controller in te stellen op het resultaat van een filter-functie, zodat de contentwordt bijgewerkt wanneer nieuwe modellen in de winkel worden geladen (wat gebeurt door de findQuery-methode in de loadMorevan de controller). Er wordt ook een query-hash toegevoegd wanneer het filterwordt aangeroepen. Dit zorgt ervoor dat er een eerste vraag aan de server wordt gesteld.

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;
});

Antwoord 2, autoriteit 25%

Wist u van de nieuw uitgebrachte Ember.ListView-component?

https://github.com/emberjs/list-view

Het werd aangekondigd tijdens de San Francisco Ember Meetup in februari. Hier is een slidedeck van Erik Bryn, een van de Ember Core-ontwikkelaars over het gebruik ervan:

http://talks.erikbryn.com/ember-list-view/


Antwoord 3, autoriteit 8%

Ik schrijf een oneindige pagineringsplug-in voor Emberop basis van het werk van @pangratz.

Stuur daar eventuele problemen door als je vragen of verbeteringen hebt die je zou willen.


Antwoord 4, autoriteit 2%

Ik raad aan om de Ember Infinity-add-on te gebruiken. Het ondersteunt Ember 1.10 tot 2.0+.Het is relatief eenvoudig in te stellen. Je hoeft alleen je route en sjabloon aan te passen.

Route (Productis voorbeeldmodel):

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 });
  }
});

Sjabloon:

{{#each model as |product|}}
  ...
{{/each}}
{{infinity-loader infinityModel=model}}

Wanneer {{infinity-loader}}component zichtbaar wordt, stuurt het een actie naar uw route, zodat het de modelarray weet bij te werken met nieuwe (opgehaalde) records.

Eerste verzoek wordt verzonden naar:

/products?per_page=12&page=1

Dus je moet ook je backend-API voorbereiden om deze queryparameters te verwerken. Het is duidelijk aanpasbaar, bekijk het Geavanceerd gebruik-gedeelte van Readme.

Opmerking:

Zowel het gebruik van ListView(@commadelimited’s antwoord) als weergaven met ArrayController(@pangratz’s antwoord) is verouderd/verwijderd vanaf Ember 2.0 als stabiele versie.

Other episodes