2015-01-31 14 views
5

मैं मार्टिजेएस (जो "वेनिला" फ्लक्स के बहुत करीब है और उसी अंतर्निहित प्रेषक का उपयोग करता है) का उपयोग करके फ़्लक्स ऐप का निर्माण कर रहा हूं। इसमें एक अंतर्निहित निर्भरता संबंध वाले स्टोर शामिल हैं। उदाहरण के लिए, UserStore वर्तमान उपयोगकर्ता को ट्रैक करता है, और InstanceStore वर्तमान उपयोगकर्ता के स्वामित्व वाले डेटा के उदाहरण ट्रैक करता है। इंस्टेंस डेटा एपीआई से असीमित रूप से लाया जाता है।फ्लक्स में AJAX: निर्भर राज्य बदलते समय ताज़ा स्टोर

प्रश्न यह है कि उपयोगकर्ता बदलते समय InstanceStore की स्थिति के साथ क्या करना है।

मुझे विश्वास है (उदाहरण के लिए SO पर @fisherwebdev द्वारा जवाब पढ़ना) कि एक्शन के निर्माता एजेक्स अनुरोधों को एजेक्स अनुरोध करने के लिए सबसे उपयुक्त है, और एक एजेक्स "सफलता" परिणामस्वरूप एक क्रिया में परिणामस्वरूप बदलने के लिए स्टोर।

तो, उपयोगकर्ता को लाने के लिए (यानी लॉग इन करें), मैं एक्शन कर निर्माता में AJAX कॉल कर रहा हूं, और जब यह हल हो जाता है, तो मैं उपयोगकर्ता के साथ एक पेलोड के रूप में RECEIVE_USER कार्रवाई भेज रहा हूं। UserStore इसकी बात सुनता है और तदनुसार इसके राज्य को अपडेट करता है।

हालांकि, यदि उपयोगकर्ता बदल गया है तो मुझे InstanceStore में सभी डेटा फिर से लाने की आवश्यकता है।

विकल्प 1: मैं InstanceStore में RECEIVE_USER को सुन सकते हैं, और अगर यह एक नया उपयोगकर्ता है, एक AJAX अनुरोध, जो बारी में एक और कार्रवाई, जो बारी में InstanceStore अद्यतन करने के लिए कारण बनता है बनाता है ट्रिगर। इसके साथ समस्या यह है कि यह कैस्केडिंग क्रियाओं की तरह लगता है, हालांकि तकनीकी रूप से यह एसिंक है इसलिए प्रेषक शायद इसे अनुमति देगा।

विकल्प 2: एक और तरीका है InstanceStore के लिए किया जाएगा UserStore द्वारा उत्सर्जित ईवेंट को बदलने और फिर अनुरोध कार्रवाई नृत्य करने के लिए सुनने के लिए है, लेकिन यह गलत भी महसूस करता है।

विकल्प 3: दो एजेक्स कॉलों को व्यवस्थित करने और अलग-अलग कार्यों को अलग करने के लिए एक्शन निर्माता के लिए एक तीसरा तरीका होगा। हालांकि, अब एक्शन निर्माता को यह जानना है कि स्टोर्स एक-दूसरे से कैसे संबंधित हैं।

Where should ajax request be made in Flux app? में उत्तरों में से एक मुझे लगता है कि विकल्प 1 सही है, लेकिन फ्लक्स डॉक्स यह भी दर्शाता है कि कार्यों को ट्रिगर करने वाले स्टोर अच्छे नहीं हैं।

उत्तर

0

विकल्प 1 मेरे लिए अवधारणात्मक रूप से सबसे अच्छा विकल्प लगता है। 2 अलग-अलग API कॉल हैं, इसलिए आपके पास ईवेंट के 2 सेट हैं।

यह कोड की एक छोटी राशि में बहुत सी घटनाएं हैं, लेकिन फ्लक्स हमेशा सरल, मानक क्रिया-> स्टोर-> दृष्टिकोण देखें का उपयोग करता है। एक बार जब आप कुछ चालाक करते हैं (जैसे विकल्प 2), ​​तो आपने इसे बदल दिया है। यदि अन्य देव अब सुरक्षित रूप से यह नहीं मान सकते कि कोई भी क्रिया प्रवाह हर दूसरे के समान सटीक काम करता है, तो आपने फ्लक्स का बड़ा लाभ खो दिया है।

हालांकि कोड में यह सबसे छोटा दृष्टिकोण नहीं होगा। मार्टिजेस ऐसा लगता है कि कम से कम फेसबुक की अपनी फ्लक्स लाइब्रेरी की तुलना में यह थोड़ा साफ होगा!

एक अलग विकल्प; अगर लॉग इन को हमेशा इंस्टेंसस्टोर को रीफ्रेश करना चाहिए, तो क्यों लॉगिन एपीआई कॉल में सभी इंस्टेंसस्टोर डेटा भी शामिल नहीं हैं?

(और इसे आगे ले जाना; 2 अलग-अलग स्टोर क्यों हैं?वे दृढ़ता से किसी भी तरह से मिलते-जुलते प्रतीत होते हैं, और कोई कारण नहीं है कि आप अभी भी लॉग इन को फिर से कॉल किए बिना इंस्टेंसस्टोर एपीआई पर कॉल नहीं कर पाएंगे)

+0

दो दुकानों के लिए कारण सभी डेटा उपयोगकर्ता से जुड़ा हुआ है कि किसी भी तरह (डेटा मूल रूप से एक ग्राफ है), तो आप या तो एक विशाल के साथ अंत शुरुआत और एक एकल में लाने है , मोनोलिथिक स्टोर, या आपके पास स्टोर निर्भरताएं हैं। – optilude

1

विकल्प 3 की तरह कुछ मेरे लिए सबसे साफ समाधान जैसा लगता है, इसके बाद विकल्प 1 मेरा तर्क:

विकल्प 2 स्टोर (प्रतीक्षा के लिए) के बीच निर्भरता को संभालने के अपेक्षित तरीके से विचलित हो जाता है, और आपको यह पता लगाने के लिए प्रत्येक परिवर्तन घटना के बाद जांच करनी होगी कि कौन से प्रासंगिक हैं और किसको अनदेखा किया जा सकता है, या कई घटना प्रकारों का उपयोग करना शुरू करें; यह बहुत गन्दा हो सकता है।

मुझे लगता है कि विकल्प 1 व्यवहार्य है; आपके द्वारा लिंक किए गए पोस्ट में Bill Fisher remarked के रूप में, एपीआई कॉल के लिए स्टोर के भीतर से कॉल करना ठीक है, बशर्ते परिणामी डेटा को नई कार्रवाइयों को कॉल करके संभाला जा सके। लेकिन ठीक है, आदर्श रूप से आदर्श नहीं है, और आप शायद चिंताओं के बेहतर अलगाव प्राप्त कर सकते हैं और कैस्केडिंग को कम कर सकते हैं यदि आप एक ही स्थान पर अपने सभी एपीआई कॉल और एक्शन दीक्षा एकत्र कर सकते हैं (यानी एक्शनक्रिएटर)। और यह विकल्प 3 के साथ संगत होगा।

हालांकि, अब एक्शन निर्माता को यह पता होना चाहिए कि स्टोर्स स्टोर एक दूसरे से कैसे संबंधित हैं।

जैसा कि मैंने इसे देखा है, कार्रवाई निर्माता को स्टोर के बारे में कुछ भी जानने की आवश्यकता नहीं है। इसे सिर्फ उपयोगकर्ता में लॉग इन करने की आवश्यकता है और फिर उपयोगकर्ता से जुड़े डेटा प्राप्त करें। चाहे यह एक एपीआई कॉल या दो के माध्यम से किया जाता है, ये तर्कसंगत रूप से बहुत ही मिलकर मिलते हैं और एक एक्शन निर्माता के दायरे में समझ में आते हैं। एक बार जब उपयोगकर्ता लॉग इन हो जाता है और डेटा प्राप्त होता है, तो आप दो क्रियाओं को निकाल सकते हैं (उदा। LOGGED_IN, GOT_USER_DATA) या यहां तक ​​कि केवल एक ही क्रिया जिसमें दोनों के लिए आवश्यक सभी डेटा शामिल हैं। किसी भी तरह से, क्रियाएं केवल एपीआई कॉल करने की प्रतिबिंबित कर रही हैं, और यह तय करने के लिए दुकानों पर निर्भर है कि इसके साथ क्या किया जाए।

मैं दोनों स्टोर्स को अपडेट करने के लिए एक ही क्रिया का उपयोग करने का सुझाव दूंगा, क्योंकि यह waitfor के लिए एक सही उपयोग केस जैसा लगता है: जब एक कार्य दोनों स्टोर्स में हैंडलर ट्रिगर करता है, तो आप इंस्टेंसस्टोर को पहले से ही उपयोगकर्तास्टोर के हैंडलर को समाप्त करने के लिए निर्देश दे सकते हैं इंस्टेंसस्टोर का हैंडलर निष्पादित करता है। यह इस तरह कुछ दिखाई देगा:

UserStore.dispatchToken = AppDispatcher.register(function(payload) { 
    switch (payload.actionType) { 

    case Constants.GOT_USER_DATA: 

     ...(handle UserStore response)... 

     break; 

    ... 
    } 
}); 

... 

InstanceStore.dispatchToken = AppDispatcher.register(function(payload) { 
    switch (payload.actionType) { 

    case Constants.GOT_USER_DATA: 

     AppDispatcher.waitFor([UserStore.dispatchToken]); 

     ...(handle InstanceStore response)... 

     break; 

    ... 
    } 
}); 
0

मैं आमतौर पर ऐसी स्थिति को हल करने के लिए वादे का उपयोग करता हूं। उदाहरण के लिए:

// UserAction.js 
var Marty  = require('marty'); 
var Constants = require('../constants/UserConstants'); 
var vow  = require('vow'); 

module.exports = Marty.createActionCreators({ 
    ... 

    handleFormEvent: function (path, e) { 
     var dfd = vow.defer(); 
     var prom = dfd.promise(); 
     this.dispatch(Constants.CHANGE_USER, dfd, prom); 
    } 
}); 


// UserStore.js 
var Marty  = require('marty'); 
var Constants = require('../constants/UserConstants'); 

module.exports = Marty.createStore({ 
    id: 'UserStore', 

    handlers: { 
     changeUser  : UserConstants.CHANGE_USER 
    }, 


    changeUser: function (dfd, __) { 
     $.ajax(/* fetch new user */) 
      .then(function (resp) { 
       /* do what you need */ 
       dfd.resolve(resp); 
      }); 
    } 
}); 



// InstanceStore.js 
var Marty  = require('marty'); 
var UserConstants = require('../constants/UserConstants'); 

module.exports = Marty.createStore({ 
    id: 'InstanceStore', 

    handlers: { 
     changeInstanceByUser : UserConstants.CHANGE_USER 
    }, 


    changeInstanceByUser: function (__, prom) { 
     prom.then(function (userData) { 
      /* OK, user now is switched */ 

      $.ajax(/* fetch new instance */) 
       .then(function (resp) { ... }); 
    } 
}); 
संबंधित मुद्दे