javascript - मॉडल डेटा और व्यवहार कहां रखा जाए?




model-view-controller angularjs (6)

AngularJS में मॉडल के बारे में यह आलेख मदद कर सकता है:

http://joelhooks.com/blog/2013/04/24/modeling-data-and-state-in-your-angularjs-application/

https://code.i-harness.com

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

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

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

बेशक मॉडल डेटा और व्यवहार सादे जावास्क्रिप्ट ऑब्जेक्ट्स या किसी भी "क्लास" पैटर्न के साथ कार्यान्वित किया जा सकता है। लेकिन AngularJS ऐसा करने का तरीका क्या होगा? सेवाओं का उपयोग करना?

तो यह इस सवाल के लिए नीचे आता है:

AngularJS सर्वोत्तम प्रथाओं के बाद, आप नियंत्रक से decoupled मॉडल कैसे कार्यान्वित करते हैं?


Angularjs दस्तावेज स्पष्ट रूप से बताता है:

कई अन्य ढांचे के विपरीत कोणीय मॉडल पर कोई प्रतिबंध या आवश्यकता नहीं बनाता है। मॉडल तक पहुंचने या बदलने के लिए उत्तराधिकारी या विशेष एक्सेसर विधियों के लिए कोई कक्षा नहीं है। मॉडल आदिम, ऑब्जेक्ट हैश, या एक पूर्ण ऑब्जेक्ट प्रकार हो सकता है। संक्षेप में मॉडल एक सादा जावास्क्रिप्ट वस्तु है।

तो इसका मतलब है कि एक मॉडल घोषित करने के लिए आप पर निर्भर है। यह एक साधारण जावास्क्रिप्ट वस्तु है।

मैं व्यक्तिगत रूप से कोणीय सेवाओं का उपयोग नहीं करता क्योंकि वे आपके द्वारा उपयोग किए जा सकने वाले सिंगलटन ऑब्जेक्ट्स जैसे व्यवहार करने के लिए थे, उदाहरण के लिए, वैश्विक अनुप्रयोगों को अपने आवेदन में रखने के लिए।


जैसा कि अन्य पोस्टर्स द्वारा बताया गया है, एंगुलर मॉडलिंग के लिए ऑफ-ऑफ-द-बॉक्स बेस क्लास प्रदान करता है, लेकिन कोई उपयोगी रूप से कई फ़ंक्शन प्रदान कर सकता है:

  1. एक विश्वसनीय API के साथ बातचीत करने और नई वस्तुओं को बनाने के तरीके
  2. मॉडल के बीच संबंध स्थापित करना
  3. बैकएंड पर बने रहने से पहले डेटा मान्य करना; रीयल-टाइम त्रुटियों को प्रदर्शित करने के लिए भी उपयोगी है
  4. अपर्याप्त HTTP अनुरोध करने से बचने के लिए कैशिंग और आलसी लोडिंग
  5. राज्य मशीन हुक (सहेजने, अद्यतन करने, बनाने, नए, आदि के पहले / बाद में)

एक पुस्तकालय जो इन सभी चीजों को अच्छी तरह से करता है ngActiveResource ( https://github.com/FacultyCreative/ngActiveResource ) है। पूर्ण प्रकटीकरण - मैंने इस पुस्तकालय को लिखा - और मैंने इसे कई एंटरप्राइज़-स्केल अनुप्रयोगों के निर्माण में सफलतापूर्वक उपयोग किया है। यह अच्छी तरह से परीक्षण किया गया है, और एक एपीआई प्रदान करता है जो रेल डेवलपर्स से परिचित होना चाहिए।

मेरी टीम और मैं सक्रिय रूप से इस पुस्तकालय को विकसित करना जारी रखता हूं, और मुझे और अधिक कोणीय डेवलपर्स इसमें योगदान देना पसंद करेंगे और युद्ध का परीक्षण करेंगे।


डीसीआई एक प्रतिमान है और इस तरह ऐसा करने का कोई कोणीय जेएस तरीका नहीं है, या तो भाषा डीसीआई का समर्थन करती है या नहीं। जेएस डीसीआई का समर्थन करता है अगर आप स्रोत परिवर्तन का उपयोग करने के इच्छुक हैं और यदि आप नहीं हैं तो कुछ कमियों के साथ। एक सी # कक्षा के मुकाबले डीसीआई के पास निर्भरता इंजेक्शन के साथ और कुछ नहीं करना है और निश्चित रूप से यह सेवा भी नहीं है। तो डीसीआई को एंजुलसजेएस के साथ करने का सबसे अच्छा तरीका डीसीआई जेएस रास्ता करना है, जो कि डीसीआई को पहली जगह कैसे तैयार किया जाता है, के करीब है। जब तक आप स्रोत परिवर्तन नहीं करते हैं, तो आप इसे पूरी तरह से करने में सक्षम नहीं होंगे क्योंकि भूमिका विधियां संदर्भ के बाहर भी ऑब्जेक्ट का हिस्सा होंगी, लेकिन आमतौर पर डीसीआई के आधार पर विधि इंजेक्शन के साथ समस्या होती है। यदि आप डीसीआई के लिए आधिकारिक साइट पर fullOO.info देखते हैं तो आप रूबी कार्यान्वयन पर एक नज़र डाल सकते हैं, वे विधि इंजेक्शन का भी उपयोग करते हैं या आप डीसीआई पर अधिक जानकारी के लिए here देख सकते हैं। यह ज्यादातर रूबी उदाहरणों के साथ है लेकिन डीसीआई सामान उस पर अज्ञेयवादी है। डीसीआई की चाबियों में से एक यह है कि सिस्टम जो करता है वह सिस्टम से अलग होता है। तो डेटा ऑब्जेक्ट बहुत गूंगा है लेकिन संदर्भ भूमिका में एक भूमिका के लिए बाध्य होने के बाद कुछ व्यवहार उपलब्ध कराते हैं। एक भूमिका केवल पहचानकर्ता है, और कुछ भी नहीं, उस पहचानकर्ता के माध्यम से किसी ऑब्जेक्ट तक पहुंचने पर, रोल विधियां उपलब्ध हैं। कोई भूमिका वस्तु / वर्ग नहीं है। विधि इंजेक्शन के साथ भूमिका विधियों की स्कॉप्लिंग बिल्कुल वर्णित लेकिन बंद नहीं है। जेएस में एक संदर्भ का एक उदाहरण हो सकता है

function transfer(source,destination){
   source.transfer = function(amount){
        source.withdraw(amount);
        source.log("withdrew " + amount);
        destination.receive(amount);
   };
   destination.receive = function(amount){
      destination.deposit(amount);
      destination.log("deposited " + amount);
   };
   this.transfer = function(amount){
    source.transfer(amount);
   };
}

मैंने इस ब्लॉग पोस्ट में उस सटीक मुद्दे से निपटने की कोशिश की है।

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

पोस्ट में $ http , $ संसाधन , और Restangular का उपयोग करके तीन दृष्टिकोण शामिल हैं।

नौकरी मॉडल पर एक कस्टम getResult() विधि के साथ, प्रत्येक के लिए कुछ उदाहरण कोड यहां दिया गया है:

Restangular (आसान peasy):

angular.module('job.models', [])
  .service('Job', ['Restangular', function(Restangular) {
    var Job = Restangular.service('jobs');

    Restangular.extendModel('jobs', function(model) {
      model.getResult = function() {
        if (this.status == 'complete') {
          if (this.passed === null) return "Finished";
          else if (this.passed === true) return "Pass";
          else if (this.passed === false) return "Fail";
        }
        else return "Running";
      };

      return model;
    });

    return Job;
  }]);

$ संसाधन (थोड़ा और अधिक शांत):

angular.module('job.models', [])
    .factory('Job', ['$resource', function($resource) {
        var Job = $resource('/api/jobs/:jobId', { full: 'true', jobId: '@id' }, {
            query: {
                method: 'GET',
                isArray: false,
                transformResponse: function(data, header) {
                    var wrapped = angular.fromJson(data);
                    angular.forEach(wrapped.items, function(item, idx) {
                        wrapped.items[idx] = new Job(item);
                    });
                    return wrapped;
                }
            }
        });

        Job.prototype.getResult = function() {
            if (this.status == 'complete') {
                if (this.passed === null) return "Finished";
                else if (this.passed === true) return "Pass";
                else if (this.passed === false) return "Fail";
            }
            else return "Running";
        };

        return Job;
    }]);

$ http (कट्टर):

angular.module('job.models', [])
    .service('JobManager', ['$q', '$http', 'Job', function($q, $http, Job) {
        return {
            getAll: function(limit) {
                var deferred = $q.defer();

                $http.get('/api/jobs?limit=' + limit + '&full=true').success(function(data) {
                    var jobs = [];
                    for (var i = 0; i < data.objects.length; i ++) {
                        jobs.push(new Job(data.objects[i]));
                    }
                    deferred.resolve(jobs);
                });

                return deferred.promise;
            }
        };
    }])
    .factory('Job', function() {
        function Job(data) {
            for (attr in data) {
                if (data.hasOwnProperty(attr))
                    this[attr] = data[attr];
            }
        }

        Job.prototype.getResult = function() {
            if (this.status == 'complete') {
                if (this.passed === null) return "Finished";
                else if (this.passed === true) return "Pass";
                else if (this.passed === false) return "Fail";
            }
            else return "Running";
        };

        return Job;
    });

ब्लॉग पोस्ट स्वयं तर्क के बारे में अधिक विस्तार से आगे बढ़ता है कि आप प्रत्येक दृष्टिकोण का उपयोग क्यों कर सकते हैं, साथ ही आपके नियंत्रकों में मॉडल का उपयोग करने के तरीके के कोड उदाहरण:

AngularJS डेटा मॉडल: $ http वीएस $ संसाधन वीएस Restangular

एक संभावना है कि कोणीय 2.0 डेटा मॉडलिंग के लिए एक अधिक मजबूत समाधान प्रदान करेगा जो सभी को एक ही पृष्ठ पर प्राप्त करता है।


यदि आप एकाधिक नियंत्रकों द्वारा उपयोग करने योग्य कुछ चाहते हैं तो आपको सेवाओं का उपयोग करना चाहिए। यहां एक सरल योगदान उदाहरण है:

myApp.factory('ListService', function() {
  var ListService = {};
  var list = [];
  ListService.getItem = function(index) { return list[index]; }
  ListService.addItem = function(item) { list.push(item); }
  ListService.removeItem = function(item) { list.splice(list.indexOf(item), 1) }
  ListService.size = function() { return list.length; }

  return ListService;
});

function Ctrl1($scope, ListService) {
  //Can add/remove/get items from shared list
}

function Ctrl2($scope, ListService) {
  //Can add/remove/get items from shared list
}




dci