ember.js - emberjs - ember model rollback
Almacenamiento en memoria caché de datos remotos en almacenamiento local con EmberData (3)
Aquí hay una manera de hacerlo. Una mezcla para sus adaptadores, con un método localStoreRecord
que puede usar para almacenar en caché el registro, por último, un inicializador para precargar la tienda.
El almacenamiento local es simplemente una clave: almacén de valores para objetos codificados, de modo que podemos almacenar todos los datos de nuestras aplicaciones en una sola clave.
Nota: esto es usando módulos es6
// app/mixins/local-storage.js
import Ember from ''ember'';
export default Ember.Mixin.create({
appName: ''myApp'',
// how many records per model to store locally, can be improved.
// needed to prevent going over localStorage''s 5mb limit
localStorageLimit: 5,
localStoreRecord: function(record) {
var data = JSON.parse(localStorage.getItem(this.appName));
data = data || {};
data[this.modelName] = data[this.modelName] || [];
var isNew = data[this.modelName].every(function(rec) {
rec.id !== record.id;
});
if (isNew) {
data[this.modelName].push(record);
if (data[this.modelName].length > this.localStorageLimit) {
data[this.modelName].shift();
}
localStorage.setItem(this.appName, JSON.stringify(data));
}
}
});
// app/adapters/skateboard.js
import DS from ''ember-data'';
import Ember from ''ember'';
import LocalStorageMixin from ''../mixins/local-storage'';
export default DS.RESTAdapter.extend(LocalStorageMixin, {
modelName: ''skateboard'',
find: function(store, type, id) {
var self = this;
var url = [type,id].join(''/'');
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
url: ''api/'' + url,
type: ''GET''
}).done(function (response) {
// cache the response in localStorage
self.localStoreRecord(response);
resolve({ type: response });
}).fail(function(jqHXR, responseStatus) {
reject(new Error(type +
'' request failed with status='' + reponseStatus);
});
});
},
updateRecord: function(store, type, record) {
var data = this.serialize(record, { includeId: true });
var id = record.get(''id'');
var url = [type, id].join(''/'');
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
type: ''PUT'',
url: ''api/'' + url,
dataType: ''json'',
data: data
}).then(function(data) {
// cache the response in localStorage
self.localStoreRecord(response);
resolve({ type: response });
}).fail(function(jqXHR, responseData) {
reject(new Error(type +
'' request failed with status='' + reponseStatus);
});
});
}
});
// app/initializers/local-storage.js
export var initialize = function(container/*, application*/) {
var appName = ''myApp'';
var store = container.lookup(''store:main'');
var data = JSON.parse(localStorage.getItem(appName));
console.log(''localStorage:'',data);
if (!data) {
return;
}
var keys = Object.keys(data);
if (keys.length) {
keys.forEach(function(key) {
console.log(key,data[key][0]);
store.createRecord(key, data[key][0]);
});
}
};
export default {
name: ''local-storage'',
after: ''store'',
initialize: initialize
};
Tengo una pregunta sobre la carga y el almacenamiento en memoria caché de objetos remotos con Ember. Estoy desarrollando una aplicación Ember que utiliza almacenamiento en el lado del servidor a través de una API REST. Algunos de los datos obtenidos rara vez cambian, por lo que es innecesario obtenerlos del servidor cada vez que la aplicación carga. Pero esta también es una pregunta para las aplicaciones que necesitan trabajar fuera de línea y aún guardar sus datos en un servidor.
Ember Data tiene un adaptador de almacenamiento incorporado para modelos persistentes a través de una API REST, y también hay un adaptador para almacenamiento local (como lo señala Ken a continuación). El problema (si es un problema) es que un modelo solo tiene un adaptador de almacenamiento, y no parece haber ningún concepto de almacenamiento en caché de los modelos, aparte de mantenerlos en la memoria.
Encontré solicitudes similares en esta lista de deseos de Ember y en los comentarios a esta charla de Tom Dale , pero no he encontrado ninguna indicación de que esta sea una característica existente en Ember.
Tengo dos preguntas (la primera es la más importante):
- ¿Cuál es la mejor manera, hoy en día, para implementar modelos en caché en almacenamiento local y sincronizarlos con datos remotos según sea necesario?
- ¿Es esta una característica que se planea incluir en Ember, o al menos algo que los mantenedores sienten que debería agregarse finalmente?
Cuando se trata de 1), puedo pensar en un par de estrategias:
a) Extienda un adaptador existente y agregue un mecanismo de sincronización remota personalizado:
App.Store.registerAdapter(''App.Post'', DS.LSAdapter.extend({
// do stuff when stuff happens
}));
b) Mantenga clases de modelo separadas, una para los objetos remotos y otra para los objetos locales, y sincronícelos según sea necesario. Con el caso estándar de Todo:
RemoteTodo –*sync*– Todo
|
UI
Estoy esperando que esta sea una pregunta real sobre novatos y que hay un buen patrón establecido para esto.
Actualizado: Encontré esta pregunta similar . Tiene una buena respuesta, pero es un poco teórica. Creo que lo que necesitaría es algunos consejos prácticos o consejos para implementaciones de ejemplo.
Existe una implementación de un adaptador de almacenamiento local que puede serle útil. Eche un vistazo a https://github.com/rpflorence/ember-localstorage-adapter
Solo para "subir" un poco este hilo, porque fue uno de los mejores resultados cuando investigué soluciones para la memoria caché local de api relajante, etc .:
Dan Gebhardt parece hacer un buen trabajo con Orbit.js y su integración en Ember: https://github.com/orbitjs/ember-orbit
Orbit es una biblioteca independiente para coordinar el acceso a las fuentes de datos y mantener sus contenidos sincronizados .
Orbit proporciona una base para crear funciones avanzadas en aplicaciones del lado del cliente, como operación fuera de línea, mantenimiento y sincronización de cachés locales, pilas de deshacer / rehacer y contextos de edición ad hoc.
Características de Orbit.js:
Admita cualquier cantidad de fuentes de datos diferentes en una aplicación y brinde acceso a ellas a través de interfaces comunes.
Permita el cumplimiento de solicitudes por diferentes fuentes, incluida la capacidad de especificar planes de prioridad y de respaldo.
Permita que los registros existan simultáneamente en diferentes estados en todas las fuentes.
Coordinar las transformaciones entre las fuentes. Handle se fusiona automáticamente siempre que sea posible, pero permite un control personalizado completo.
Permitir las transformaciones de bloqueo y no bloqueo.
Permitir solicitudes sincrónicas y asincrónicas.
Soporte de transacciones y deshacer / rehacer mediante el seguimiento de inversos de operaciones.
Trabaja con objetos JavaScript simples
Y no te pierdas su gran discurso y diapositivas sobre Orbit:
Introducción a Orbit.js
( ACTUALIZACIÓN : agregué más información descriptiva de las páginas de Orbit, ya que mi publicación se votó negativamente por "solo" hacer referencia a recursos externos y no contener la solución real en sí misma. Pero Orbit me parece como la solución, y la única manera de " incluir "esto aquí es a través de enlaces")