javascript - ExtJS:स्टोअर परिभाषा के लिए दूरस्थ लोड किए गए सिंगलटन मानों का उपयोग करना




parse.com singleton store (4)

मुझे यह समझने की कोशिश करने में कुछ परेशानी हो रही है कि यह कैसे करना है (यदि यह संभव है)।

मेरे पास ऐप है जो parse.com का उपयोग करता है इसे स्टोर करने के लिए, यह बात है कि मैं चाहता हूं कि प्रत्येक उपयोगकर्ता को एक अलग parse.com खाता होना चाहिए ताकि उनका डेटा सेट जो कुछ अलग हो सके। इसलिए मैंने एक सिंगलटन (सेटिंग्स) बनाया जो उपयोगकर्ता के एड आईडी और एपीआईके को संग्रहीत करता है, जो एक सामान्य parse.com खाते से लोड होता है जो मेरे द्वारा प्रबंधित होता है और प्रत्येक उपयोगकर्ता के ईमेल, ऐप आईडी और एपीकी में शामिल होता है, इसलिए जब वे ऐप में प्रवेश करते हैं उपयोगकर्ता का ऐप आईडी और एपीकी

मुझे अपने स्टोर की परिभाषाओं में उन सेटिंग्स, ऐप आईडी और एपीकी का उपयोग करने की आवश्यकता है, क्योंकि उन्हें उन्हें हेडर में भेजने की आवश्यकता है। ऐप लॉन्च होने पर मैंने अपने सिंगलटन के ग्लोबल्स को सेट करने के लिए कुछ परीक्षण किए हैं, लेकिन स्टोर्स परिभाषा के समय उन "ग्लोबल्स" दोनों ही अशक्त हैं, क्योंकि ऐप ने अब तक लॉन्च नहीं किया है।

यहाँ मेरा कुछ कोड है इसलिए मैं खुद को थोड़ा साफ़ कर सकता हूं क्योंकि मुझे पता है कि यह समझने में सबसे आसान बात नहीं है।

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

दुकान

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

इस के आसपास का रास्ता क्या है?

वैसे .. अगर कोई इस सूत्र के लिए उचित नाम के बारे में सोच सकता है तो कृपया इसे बदलने या सुझाव देने में संकोच न करें।


Answers

कुछ ऐसा प्रयास करें:

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

मैं इसे पूरा करने के लिए मार्गों का उपयोग करने का सुझाव दूंगा, क्योंकि आप एक्स्टजे 6 का प्रयोग कर रहे हैं। यह पूरी तरह से बॉक्स से बाहर है, लेकिन मुझे लगता है कि यह आपकी स्थिति के लिए आदर्श होगा। इस तरीके से आप यह सुनिश्चित कर सकते हैं कि जब एक मार्ग कहा जाता है और आपके आवेदन का एक हिस्सा लोड होता है, तो आप हमेशा कुछ चेक कर सकते हैं उदाहरण के लिए उपयोगकर्ता क्रेडेंशियल्स की जांच के लिए यह बहुत उपयोगी हो सकता है। मार्गों के बारे में अधिक जानकारी यहां पाई जा सकती है। और यह एक महान पोस्ट है जब आप रूट के जरिए उपयोगकर्ता सत्र को संभालना चाहते हैं।

सिंगलटन:

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

बेस स्टोर:

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

चीजें स्टोर:

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

आपका मुख्य नियंत्रक:

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

मुझे लगता है कि प्रॉक्सी की परिभाषा को 'चीजों' के कंस्ट्रक्टर को नीचे दिए गए अनुसार परिभाषित करके समस्या का समाधान किया जा सकता है

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

जब प्रॉक्सी की परिभाषा निर्माता के अंदर होती है, सेटिंग्स.appId और Settings.apiKey को केवल 'MyApp.store.Things' के निर्माण के समय में हल किया जाता है


समस्या सबसे अधिक संभावना बंद करने के कार्यों से जुड़ा हुआ है, उदाहरण के लिए जब आप कॉलबैक पंजीकृत करते हैं तो एक तर्क के रूप में। उस स्थिति में "इस" का एक अलग मूल्य हो सकता है, इसलिए उन्हें इसके बजाय "मुझे" उपयोग करने की आवश्यकता है।





javascript extjs parse.com singleton store