javascript ember.js rsvp.js

javascript - EmberJS: ¿cómo cargar varios modelos en la misma ruta?



ember.js rsvp.js (5)

Si bien no soy nuevo en el desarrollo web, soy bastante nuevo en los frameworks MVC del lado del cliente. Investigué un poco y decidí probarlo con EmberJS. Revisé la guía de TodoMVC y tenía sentido para mí ...

Configuré una aplicación muy básica; ruta de índice, dos modelos y una plantilla. Tengo un script php del lado del servidor ejecutándose que devuelve algunas filas db.

Una cosa que me confunde mucho es cómo cargar múltiples modelos en la misma ruta. He leído información sobre el uso de un setupController, pero todavía no estoy claro. En mi plantilla, tengo dos tablas que estoy intentando cargar con filas db no relacionadas. En una aplicación web más tradicional, acababa de emitir sentencias sql y buclearlas para completar las filas. Tengo dificultades para traducir este concepto a EmberJS.

¿Cómo cargo varios modelos de datos no relacionados en la misma ruta?

Estoy usando las últimas libs de Ember y Ember Data.

Actualizar

aunque la primera respuesta brinda un método para manejarlo, la segunda respuesta explica cuándo es apropiado y los diferentes métodos para cuando no es apropiado.


TENER CUIDADO:

Desea tener cuidado acerca de si es apropiado o no devolver varios modelos en su gancho modelo. Hágase esta simple pregunta:

  1. ¿Mi ruta carga datos dinámicos basados ​​en la url usando slug :id ? es decir, this.resource(''foo'', {path: '':id''});

Si respondiste sí

¡¡No intente cargar múltiples modelos desde el gancho modelo en esa ruta !!! La razón radica en la forma en que Ember maneja el enlace a las rutas. Si proporciona un modelo al enlazar con esa ruta ( {{link-to ''foo'' model}} , transitionTo(''foo'', model) ) omitirá el gancho del modelo y usará el modelo suministrado. Esto probablemente sea problemático ya que esperaba varios modelos, pero solo se entregaría un modelo. Aquí hay una alternativa:

Hazlo en setupController / afterModel

App.IndexRoute = Ember.Route.extend({ model: function(params) { return $.getJSON(''/books/'' + params.id); }, setupController: function(controller, model){ this._super(controller,model); controller.set(''model2'', {bird:''is the word''}); } });

Ejemplo: http://emberjs.jsbin.com/cibujahuju/1/edit

Si lo necesita para bloquear la transición (como lo hace el gancho modelo) devuelva una promesa del gancho afterModel . Necesitará realizar un seguimiento manual de los resultados de ese gancho y conectarlos a su controlador.

App.IndexRoute = Ember.Route.extend({ model: function(params) { return $.getJSON(''/books/'' + params.id); }, afterModel: function(){ var self = this; return $.getJSON(''/authors'').then(function(result){ self.set(''authors'', result); }); }, setupController: function(controller, model){ this._super(controller,model); controller.set(''authors'', this.get(''authors'')); } });

Ejemplo: http://emberjs.jsbin.com/diqotehomu/1/edit

Si respondiste no

Adelante, devolvamos varios modelos del anzuelo modelo de la ruta:

App.IndexRoute = Ember.Route.extend({ model: function() { return { model1: [''red'', ''yellow'', ''blue''], model2: [''green'', ''purple'', ''white''] }; } });

Ejemplo: http://emberjs.jsbin.com/tuvozuwa/1/edit

Si es algo que se debe esperar (como una llamada al servidor, algún tipo de promesa)

App.IndexRoute = Ember.Route.extend({ model: function() { return Ember.RSVP.hash({ model1: promise1, model2: promise2 }); } });

Ejemplo: http://emberjs.jsbin.com/xucepamezu/1/edit

En el caso de Ember Data

App.IndexRoute = Ember.Route.extend({ var store = this.store; model: function() { return Ember.RSVP.hash({ cats: store.find(''cat''), dogs: store.find(''dog'') }); } });

Ejemplo: http://emberjs.jsbin.com/pekohijaku/1/edit

Si uno es una promesa, y el otro no, todo está bien, RSVP gustosamente usará ese valor

App.IndexRoute = Ember.Route.extend({ var store = this.store; model: function() { return Ember.RSVP.hash({ cats: store.find(''cat''), dogs: [''pluto'', ''mickey''] }); } });

Ejemplo: http://emberjs.jsbin.com/coxexubuwi/1/edit

¡Mezcla y combina y diviértete!

App.IndexRoute = Ember.Route.extend({ var store = this.store; model: function() { return Ember.RSVP.hash({ cats: store.find(''cat''), dogs: Ember.RSVP.Promise.cast([''pluto'', ''mickey'']), weather: $.getJSON(''weather'') }); }, setupController: function(controller, model){ this._super(controller, model); controller.set(''favoritePuppy'', model.dogs[0]); } });

Ejemplo: http://emberjs.jsbin.com/joraruxuca/1/edit


La última versión de JSON-API tal como se implementó en Ember Data v1.13, admite la agrupación de diferentes recursos en la misma solicitud, si no le importa modificar los puntos finales API.

En mi caso, tengo un punto final de session . La sesión se relaciona con un registro de usuario, y el registro del usuario se relaciona con varios modelos que siempre deseo cargar en todo momento. Es muy agradable que todo entre con la única solicitud.

Una advertencia por especificación es que todas las entidades que devuelve deben estar vinculadas de alguna manera a la entidad primaria que se recibe. Creo que los datos de ascuas solo atravesarán las relaciones explícitas al normalizar el JSON.

En otros casos, ahora prefiero diferir la carga de modelos adicionales hasta que la página ya esté cargada, es decir, para paneles de datos separados o lo que sea, de modo que al menos la página se renderiza lo más rápido posible. Al hacer esto, hay algunas pérdidas / cambios con el estado de carga de error "automático" para considerar.


Puede usar Ember.RSVP.hash para cargar varios modelos:

app/routes/index.js

import Ember from ''ember''; export default Ember.Route.extend({ model() { return Ember.RSVP.hash({ people: this.store.findAll(''person''), companies: this.store.findAll(''company'') }); }, setupController(controller, model) { this._super(...arguments); Ember.set(controller, ''people'', model.people); Ember.set(controller, ''companies'', model.companies); } });

Y en su plantilla puede hacer referencia a people y companies para obtener los datos cargados:

app/templates/index.js

<h2>People:</h2> <ul> {{#each people as |person|}} <li>{{person.name}}</li> {{/each}} </ul> <h2>Companies:</h2> <ul> {{#each companies as |company|}} <li>{{company.name}}</li> {{/each}} </ul>

Este es un Twiddle con esta muestra: https://ember-twiddle.com/c88ce3440ab6201b8d58


Si usa Ember Data, se vuelve aún más simple para los modelos no relacionados:

import Ember from ''ember''; import DS from ''ember-data''; export default Ember.Route.extend({ setupController: function(controller, model) { this._super(controller,model); var model2 = DS.PromiseArray.create({ promise: this.store.find(''model2'') }); model2.then(function() { controller.set(''model2'', model2) }); } });

Si solo desea recuperar la propiedad de un objeto para el model2 , use DS.PromiseObject lugar de DS.PromiseArray :

import Ember from ''ember''; import DS from ''ember-data''; export default Ember.Route.extend({ setupController: function(controller, model) { this._super(controller,model); var model2 = DS.PromiseObject.create({ promise: this.store.find(''model2'') }); model2.then(function() { controller.set(''model2'', model2.get(''value'')) }); } });


Utilizo algo así como la respuesta que proporcionó Marcio, pero se ve así:

var products = Ember.$.ajax({ url: api + ''companies/'' + id +''/products'', dataType: ''jsonp'', type: ''POST'' }).then(function(data) { return data; }); var clients = Ember.$.ajax({ url: api + ''clients'', dataType: ''jsonp'', type: ''POST'' }).then(function(data) { return data; }); var updates = Ember.$.ajax({ url: api + ''companies/'' + id + ''/updates'', dataType: ''jsonp'', type: ''POST'' }).then(function(data) { return data; }); var promises = { products: products, clients: clients, updates: updates }; return Ember.RSVP.hash(promises).then(function(data) { return data; });