2014-08-29 4 views
7

मैं कोणीय के लिए काफी नया हूं इसलिए शायद मैं असंभव पूछ रहा हूं लेकिन वैसे भी, यह मेरी चुनौती है।AngularJS में oboe.js का उपयोग कर JSON स्ट्रीमिंग के लिए एक समाधान?

चूंकि हमारा सर्वर जेएसओएन डेटा को पैगनेट नहीं कर सकता है, इसलिए मैं JSON स्ट्रीम करना चाहता हूं और इसे पृष्ठ द्वारा नियंत्रक के मॉडल में पृष्ठ जोड़ना चाहता हूं। उपयोगकर्ता को पूरी स्ट्रीम लोड होने की प्रतीक्षा नहीं करनी है, इसलिए मैं प्रत्येक एक्स (पेजसाइज) रिकॉर्ड्स के लिए दृश्य को रीफ्रेश करता हूं।

मुझे JSON स्ट्रीम को पार्स करने के लिए oboe.js मिला और इसे मेरे प्रोजेक्ट में बॉवर का उपयोग करके जोड़ा। (बॉवर इंस्टॉल ओबो - सेव)।

मैं स्ट्रीमिंग के दौरान नियंत्रक मॉडल को अपडेट करना चाहता हूं। मैंने pomises के $ q कार्यान्वयन का उपयोग नहीं किया, क्योंकि केवल एक ही है .resolve (...) संभव है और मैं स्ट्रीम के माध्यम से लोड किए गए डेटा के कई पेज चाहता हूं ताकि प्रत्येक पृष्ठ के साथ $ पाचन को बुलाया जा सके। शोकहारा सेवा है कि कहा जाता है

है/सेवा/कार्य/खोज मैं एक खोज समारोह जो मैं नियंत्रक के भीतर से फोन के साथ एक कारखाना बनाया:

'use strict'; 

angular.module('myStreamingApp') 
    .factory('Stream', function() { 
     return { 
      search: function(schema, scope) { 
       var loaded = 0; 
       var pagesize = 100; 
       // JSON streaming parser oboe.js 
       oboe({ 
        url: '/service/' + schema + '/search' 
       }) 
         // process every node which has a schema 
         .node('{schema}', function(rec) { 
          // push the record to the model data 
          scope.data.push(rec); 
          loaded++; 
          // if there is another page received then refresh the view 
          if (loaded % pagesize === 0) { 
           scope.$digest(); 
          } 
         }) 
         .fail(function(err) { 
          console.log('streaming error' + err.thrown ? (err.thrown.message):''); 
         }) 
         .done(function() { 
          scope.$digest(); 
         }); 
      } 
     }; 
    }); 

मेरे नियंत्रक:

'use strict'; 
angular.module('myStreamingApp') 
    .controller('MyCtrl', function($scope, Stream) { 
     $scope.data = []; 
     Stream.search('tasks', $scope); 
    }); 

यह काम करने के लिए सभी seams। थोड़ी देर बाद सिस्टम धीमा हो जाता है और ब्राउज़र को रीफ्रेश करने के बाद http कॉल समाप्त नहीं होता है। जब भी बहुत सारे रिकॉर्ड लोड होते हैं तो ब्राउज़र (क्रोम) क्रैश हो जाता है। हो सकता है कि मैं गलत ट्रैक पर हूं क्योंकि फ़ैक्टरी खोज फ़ंक्शन के दायरे को पार करने से सही "अनुभव" नहीं होता है और मुझे संदेह है कि उस दायरे पर $ पाचन को कॉल करने से मुझे परेशानी हो रही है। इस विषय पर किसी भी विचार का स्वागत है। आप इसे लागू करने जहां कारखाना (या सेवा) एक वादा लौट सकते हैं और मैं नियंत्रक में

$scope.data = Stream.search('tasks'); 

इस्तेमाल कर सकते हैं पर एक विचार है, खासकर अगर।

उत्तर

14

मैंने थोड़ा आगे खोद दिया और निम्नलिखित समाधान के साथ आया। यह किसी की मदद कर सकता है:

कारखाने (नामित स्ट्रीम) में एक खोज फ़ंक्शन है जो अजाक्स अनुरोध और कॉलबैक फ़ंक्शन के लिए पैरामीटर पास किया गया है। धारा द्वारा लोड किए गए डेटा के प्रत्येक पृष्ठ के लिए कॉलबैक कहा जा रहा है। कॉलबैक फ़ंक्शन को deferred.promise के माध्यम से बुलाया जाता है ताकि प्रत्येक पृष्ठ के साथ स्कोप स्वचालित रूप से अपडेट हो सके। खोज फ़ंक्शन तक पहुंचने के लिए मैं एक सेवा (नामित खोज) का उपयोग करता हूं जो प्रारंभ में डेटा की खाली मिट्टी देता है। चूंकि धारा में फैक्ट्री की प्रगति होती है, सेवा द्वारा पारित कॉलबैक फ़ंक्शन को कॉल किया जाता है और पृष्ठ डेटा में जोड़ा जाता है।

अब मैं एक नियंत्रक के भीतर खोज सेवा फ़ॉर्म को कॉल कर सकता हूं और स्कोप डेटा सरणी में वापसी मान असाइन कर सकता हूं।

सेवा और कारखाने:

'use strict'; 
angular.module('myStreamingApp') 
     .service('Search', function(Stream) { 
      return function(params) { 
       // initialize the data 
       var data = []; 
       // add the data page by page using a stream 
       Stream.search(params, function(page) { 
        // a page of records is received. 
        // add each record to the data 
        _.each(page, function(record) { 
         data.push(record); 
        }); 
       }); 
       return data; 
      }; 
     }) 
     .factory('Stream', function($q) { 
      return { 
       // the search function calls the oboe module to get the JSON data in a stream 
       search: function(params, callback) { 
        // the defer will be resolved immediately 
        var defer = $q.defer(); 
        var promise = defer.promise; 
        // counter for the received records 
        var counter = 0; 
        // I use an arbitrary page size. 
        var pagesize = 100; 
        // initialize the page of records 
        var page = []; 
        // call the oboe unction to start the stream 
        oboe({ 
         url: '/api/' + params.schema + '/search', 
         method: 'GET' 
        }) 
          // once the stream starts we can resolve the defer. 
          .start(function() { 
           defer.resolve(); 
          }) 
          // for every node containing an _id 
          .node('{_id}', function(node) { 
           // we push the node to the page 
           page.push(node); 
           counter++; 
           // if the pagesize is reached return the page using the promise 
           if (counter % pagesize === 0) { 
            promise.then(callback(page)); 
            // initialize the page 
            page = []; 
           } 
          }) 
          .done(function() { 
           // when the stream is done make surethe last page of nodes is returned 
           promise.then(callback(page)); 
          }); 
        return promise; 
       } 
      }; 
     }); 

अब मैं एक नियंत्रक के भीतर से सेवा को कॉल और गुंजाइश के लिए सेवा की प्रतिक्रिया प्रदान कर सकते हैं:

$scope.mydata = Search({schema: 'tasks'}); 

अद्यतन अगस्त 30, 2014

मैंने उपरोक्त समाधान के साथ एक कोणीय-ओबो मॉड्यूल बनाया है जो थोड़ा और अधिक संरचित है। https://github.com/RonB/angular-oboe

संबंधित मुद्दे