tutorial español javascript extjs parse.com singleton store

javascript - extjs 6 tutorial español



ExtJS: Uso de valores singleton cargados remotamente para la definición de la tienda (3)

Tengo problemas para tratar de descubrir cómo hacerlo (si es posible).

Tengo una aplicación que usa parse.com para almacenar sus datos, lo que quiero es que cada usuario tenga una cuenta de parse.com diferente para que sus conjuntos de datos no se crucen en absoluto. Así que creé un singleton (Configuración) que almacena la aplicación id y apiKey, que se cargan desde una cuenta general de parse.com administrada por mí y que contiene el correo electrónico de cada usuario, ID de aplicación y clave de acceso, de modo que cuando inician sesión en la aplicación se pone la aplicación y la clave del usuario.

Lo que pasa es que necesito usar esas configuraciones, appId y apiKey, en las definiciones de mis tiendas, ya que necesito enviarlas en los encabezados. He hecho algunas pruebas al intentar configurar los valores globales de mi singleton cuando se inicia la aplicación, pero en el momento de la definición de las tiendas, ambos de esos "globales" son nulos, ya que la aplicación aún no se ha lanzado.

Aquí hay algunos de mis códigos, así que puedo aclararme un poco, ya que sé que esto no es lo más fácil de entender.

Application.js

Ext.define(''Settings'', { singleton: true, appId: null, apiKey: null }); Ext.define(''MyApp.Application'', { extend: ''Ext.app.Application'', name: ''MyApp'', stores: [], launch: function () { Ext.create(''MyApp.store.Settings'').load({ params: { ''where'': ''{"email": "[email protected]"}'' //email is supposed to be a user input but for the sakes of testing I just made it static }, callback: function(records){ var s = records[0]; Settings.appId = s.get(''appId''); Settings.apiKey = s.get(''apiKey''); Parse.initialize(Settings.appId, Settings.apiKey); } }); }, onAppUpdate: function () { Ext.Msg.confirm(''Application Update'', ''This application has an update, reload?'', function (choice) { if (choice === ''yes'') { window.location.reload(); } } ); } });

Almacenar

Ext.define(''MyApp.store.Things'', { extend: ''Ext.data.Store'', model: ''MyApp.model.Thing'', proxy: { type: ''rest'', api: { read: ''https://api.parse.com/1/classes/Thing'', create: ''https://api.parse.com/1/classes/Thing'' }, reader: { type: ''json'', rootProperty: ''results'' }, useDefaultXhrHeader: false, withCredentials: false, headers: { ''X-Parse-Application-Id'': Settings.appId, //this is null at the time of definition, but I want it to be the newly fetched value at the time of app launch ''X-Parse-REST-API-Key'': Settings.apiKey, //this is obviously null as well ''Content-Type'': ''application/json'' } }, autoLoad: true, autoSync: true });

¿Cuál es el camino alrededor de esto?

Por cierto ... si alguien puede pensar en un nombre propio para este hilo, siéntete libre de cambiarlo o sugerirlo.


Pruebe algo como:

Ext.define(''Settings'', { singleton: true, appId: null, apiKey: null }); Ext.define(''MyApp.store.Things'', { extend: ''Ext.data.Store'', model: ''MyApp.model.Thing'', proxy: { type: ''rest'', api: { read: ''https://api.parse.com/1/classes/Thing'', create: ''https://api.parse.com/1/classes/Thing'' }, reader: { type: ''json'', rootProperty: ''results'' }, useDefaultXhrHeader: false, withCredentials: false, }, //autoLoad: true, autoSync: true }); Ext.define(''MyApp.Application'', { extend: ''Ext.app.Application'', name: ''MyApp'', stores: [''Things''], launch: function() { var settings = Ext.create(''MyApp.store.Settings''); settings.on(''load'', function() { var things = Ext.getStore(''Things''); things.getProxy().setHeaders({ ''X-Parse-Application-Id'': Settings.appId, ''X-Parse-REST-API-Key'': Settings.apiKey, ''Content-Type'': ''application/json'' }); things.load(); }); settings.load({ params: { ''where'': ''{"email": "[email protected]"}'' //email is supposed to be a user input but for the sakes of testing I just made it static }, callback: function(records) { var s = records[0]; Settings.appId = s.get(''appId''); Settings.apiKey = s.get(''apiKey''); Parse.initialize(Settings.appId, Settings.apiKey); } }); }, onAppUpdate: function() { Ext.Msg.confirm(''Application Update'', ''This application has an update, reload?'', function(choice) { if (choice === ''yes'') { window.location.reload(); } } ); } });


Sugeriría usar rutas para lograr esto, ya que está utilizando ExtJs 6. Está completamente fuera de la caja, pero creo que sería ideal para su situación. De esta forma, puede simplemente asegurarse de que cuando se invoca una ruta y se carga una parte de su aplicación, siempre puede hacer algunas comprobaciones. Esto puede ser muy útil para verificar credenciales de usuario, por ejemplo. Puede encontrar más información sobre rutas aquí. Y esta es una gran publicación cuando quieres manejar sesiones de usuario a través de rutas.

El singleton:

Ext.define(''Settings'', { singleton: true, appId: null, apiKey: null });

La tienda base:

Ext.define(''Base'', { extend: ''Ext.data.Store'', alias: ''store.base'', storeId: ''base'', autoLoad: false, proxy: { type: ''rest'', useDefaultXhrHeader: false, withCredentials: false }, listeners: { beforeload: function(store, operation, eOpts) { store.getProxy().headers = { ''X-Parse-Application-Id'': Settings.appId, ''X-Parse-REST-API-Key'': Settings.apiKey, ''Content-Type'': ''application/json'' } } } });

La tienda de cosas:

Ext.define(''MyApp.store.Things'', { extend: ''MyApp.store.Base'', alias: ''store.things'', model: ''MyApp.model.Thing'', storeId: ''things'', requires: [ ''Settings'' ], proxy: { api: { read: ''https://api.parse.com/1/classes/Thing'', create: ''https://api.parse.com/1/classes/Thing'' }, reader: { type: ''json'', rootProperty: ''results'' } }, autoLoad: false, // --> set to false autoSync: true });

Su MainController:

Ext.define(''MyApp.view.main.MainController'', { extend : ''Ext.app.ViewController'', requires: [ ''Settings'' ], stores: [ ''Things'' ], routes : { ''user/:id'' : { before : ''onBeforeUser'', action : ''onUser'' } }, onBeforeUser : function(id, action) { Ext.create(''MyApp.store.Settings'').load({ params: { ''where'': ''{"email": "[email protected]"}'' //email is supposed to be a user input but for the sakes of testing I just made it static }, callback: function(records){ var s = records[0]; Settings.appId = s.get(''appId''); Settings.apiKey = s.get(''apiKey''); Parse.initialize(Settings.appId, Settings.apiKey); action.resume(); } }); // or even better Ext.Ajax.request({ url: ''url/to/the/api'', params: { ''where'': ''{"email": "[email protected]"}'' //email is supposed to be a user input but for the sakes of testing I just made it static }, success: function(response, opts) { var obj = Ext.decode(response.responseText); Settings.appId = obj.appId; Settings.apiKey = obj.apiKey; Parse.initialize(Settings.appId, Settings.apiKey); action.resume(); }, failure: function(response, opts) { action.stop(true); } }); }, onUser : function(id) { Ext.getStore(''things'').load(); } });


Creo que el problema se puede resolver moviendo la definición del proxy al constructor del almacén de ''Cosas'' como se indica a continuación.

Ext.define(''MyApp.store.Things'', { extend: ''Ext.data.Store'', model: ''MyApp.model.Thing'', autoLoad: true, autoSync: true, constructor: function(config) { config = Ext.apply({ proxy: { type: ''rest'', api: { read: ''https://api.parse.com/1/classes/Thing'', create: ''https://api.parse.com/1/classes/Thing'' }, reader: { type: ''json'', rootProperty: ''results'' }, useDefaultXhrHeader: false, withCredentials: false, headers: { ''X-Parse-Application-Id'': Settings.appId, ''X-Parse-REST-API-Key'': Settings.appId, ''Content-Type'': ''application/json'' } } }, config); this.callParent([config]); } });

Cuando la definición de proxy está dentro del constructor, Settings.appId y Settings.apiKey se resuelven solo en el momento de la creación de la instancia de ''MyApp.store.Things''.