How do I prefetch url's in ionic/angularjs?

前端 未结 4 1646
渐次进展
渐次进展 2021-02-19 12:11

I am pretty new to ionic 1 and I am working on an application (with Ionic 1 and angular js) with multiple URLs where each URL brings up a list of categories, followed by a list

相关标签:
4条回答
  • 2021-02-19 12:46

    Update - As the OP is already aware of and using localStorage, thus additional suggestions :-

    In that case, you could either call all of your service methods for fetching data at startup or you could use a headless browser such as 'PhantomJS' to visit these URLs at startup and fetch the data.

    Thus, your code would look something like :-

    var webPage = require('webpage');
    
    var page = webPage.create();
    
    page.open('http://www.google.com/', function(status) {
      console.log('Status: ' + status);
      // Do other things here...
    });
    

    For more information, regarding PhantomJS, please refer to the following links :-

    http://phantomjs.org/ http://phantomjs.org/api/webpage/method/open.html

    Earlier Suggestions

    Make an HTTP request in your service to fetch the data and store it to localStorage, as is shown below :-

    $http.get('url', function(response) {
    var obj = response.data;
    window.localStorage.setItem('key', JSON.stringify(obj)); // Store data to localStorage for later use
    });
    

    For fetching data :-

    var cachedData = JSON.parse(window.localStorage.getItem('key')); // Load cached data stored earlier
    

    Please refer to the following link for detailed information regarding 'localStorage' :- https://www.w3schools.com/html/html5_webstorage.asp

    Hope this helps!

    0 讨论(0)
  • 2021-02-19 12:48

    I am assuming you don't want to load data in next screens, deliver user flawless experience.

    Yes you can start loading URLs on you very first page as you want them to get the data you want to use in future screens.

    In terms of storage

    1. In AngularJs if you want something to persist throughout the application scope you should use $rootscope[beware keeping lot of data may leads to memory issues, you need to clear it regularly].
    2. Or another option is to store it in Localstorage. And fetch as per your need.
    3. If you want you can share those arrays between different controllers of screens.

    While loading[response getting from server] you can do two things 1. get single JSON response having all the data 2.have multiple urls, and load them serially.

    As per your requirement of loading 5th (page)screen data in advance it's not good practice, and even stop user from seeing updates but as it's your requirement. We've couple of approaches:

    1. Add all the category and their respective details as per your pastebin like cardiac then it's details.. kidney then details.. You can do this with managing hierarchies [categories] like parent main group and it's child sub group in JSONArray and details in JSONObject. (This change would be on sender side -server)

    You need to load only one url to get all data. So you don't need to load with different urls like now your doing. But beware this would be a big Json. So when you store it separate the categories and required data [screen-wise requirements] and store in local storage so easy for access.

    1. Another approach would be you have to provide your [category] subgroup names to load so the loading would be like firing same URL with different category names to get data and store it in local storage.

    This may lead to fire around 10-15[depends on your categories] urls may affect the UI thread response. This won't need any changes on your server side response.

    **

    Programmatically approach to load urls sequentially:

    **

    URL Loading: This method will get detail of particular category [id or anything works for you]. This will fire a http request and return a result.

    getCategoryDetails(category){
    url = url+category;
    return $http({ 
            method: 'GET', 
            url: url, 
            headers: --
        }).then(function onSuccess(response) {  //<--- `.then` transforms the promise here
    

    //You can ether store in local storage return response }, function onError(response) { throw customExceptionHadnler.getErrorMsg(response.status, response.data); }); }

    Parallel : This method will do it in parallel, we just load categories[ids] as we have all of them and then use $q.all to wait for all the urls loading to finish.

     function loadUrlsParallel(urls) {
         var loadUrls = []
         for(var i = 0; i < urls.length; i++) {
             loadUrls.push(getCategoryDetails(urls[i]))
         }
         return $q.all(loadUrls) 
    }
    

    First API: This method to load first url and then Loading urls in parallel call above method

    getListOfCategories(){
    url = url;
    return $http({ 
            method: 'GET', 
            url: url, 
            headers: --
        }).then(function onSuccess(response) {  //<--- `.then` transforms the promise here
    

    //You can ether store in local storage or directly send response return response }, function onError(response) { throw customExceptionHadnler.getErrorMsg(response.status, response.data); }); }

    urls : you have to prepare list of urls with appending category to load after loading first url[expecting this returns you all the categories you will require in your app beforehand] and pass to loadUrlsParallel method.

    You can write loadUrl methods as per your convenience, here whatever is given is foe example purpose so may not run as it is.

    You can load API responses every where from local storage where you've stored after API calls, So this will not ask you to execute API calls on every laoding of pages[screen]

    Hope this helps you and solves your prob.

    0 讨论(0)
  • 2021-02-19 12:59

    You can make multiple Asynchronous service calls in background using $q. Make a list of URL's in an array and call them at once using $q.all(listOfURL). Using promises retrieve each response.

    By making this asynchronous you can save lot of time.

    After getting response you can either store them in $rootScope or in localStorage/sessionStorage.

    0 讨论(0)
  • 2021-02-19 13:00

    Best way to share data between different views in angular is to use a service as it is a singleton and can be used in other controllers. In your main controller you can prefetch your lists of categories asynchronously through a service which can be shared for next views.Below is a small demo which you refer

    angular.module("test").service("testservice",function('$http',$q){
        var lists = undefined;
        // fetch all lists in deferred technique
        this.getLists = function() {
          // if lists object is not defined then start the new process for fetch it
          if (!lists) {
            // create deferred object using $q
            var deferred = $q.defer();
             // get lists form backend
            $http.get(URL)
              .then(function(result) {
                // save fetched posts to the local variable
                lists = result.data;
                // resolve the deferred
                deferred.resolve(lists);
              }, function(error) {
                //handle error
                deferred.reject(error);
              });
            // set the posts object to be a promise until result comeback
            lists = deferred.promise;
          }
    
          // in any way wrap the lists object with $q.when which means:
          // local posts object could be:
          // a promise
          // a real lists data
          // both cases will be handled as promise because $q.when on real data will resolve it immediately
          return $q.when(lists);
        };
    this.getLists2=function(){
    //do it similarly as above
    };
    }).controller("mainController",function(testservice,$scope){
        $scope.lists1=testervice.getLists()
            .then(function(lists) {
            //do something 
            });
        };
        $scope.lists2=testervice.getLists2()
            .then(function(lists) {
            //do something 
            });
        };
        $scope.lists1();
        $scope.lists2();
    }).controller("demoController1",function(testservice,$scope){
        $scope.lists1=testervice.getLists()
            .then(function(lists) {
            //do something 
            });
        };
        $scope.lists2=testervice.getLists2()
            .then(function(lists) {
            //do something 
            });
        };
        $scope.lists1();
        $scope.lists2();
    });
    
    0 讨论(0)
提交回复
热议问题