简体   繁体   中英

AngularJs: Sharing data across controllers

I am using super heroic Angularjs in my application. I have a couple of pages like home.html , project.html , map.html . Each pages has a controller associated with it eg HomeCtrl , ProjectCtrl , MapCtrl . In my home.html user can create a project or navigate to project.html . In project.html I have list of all projects. When user clicks on a project he is navigated to map.html where I have some information regarding to project. I am using ngRoute for routing between the views. I am facing some challenges to share data across the controllers. I have created a service called dataFactory which stores all the data retrieved from backend. In my project.html view, I load all the data from backend and store them in service. When user lands into a project I use data stored in the dataFactory . The concern is that when user refreshes the page when he is on the map.html, all the data which are stored in dataFactory are wiped out and not loaded back cause data loading happens in the project.html page. I don't know how can I deal with it. I can not make a call to backend in every controller to get the data. I am planning to load the common data in app.run() method. But in that case I have to broadcast/emit the events to notify controllers, which will also be messier and will eventually lead to errors cause I know my application is going to be a huge application.

There is a solution but it needs some additional configuration while making routes in your $routeProvider , You can resolve your route when you have your data fetch from the backend. By using this method if a user refreshes the page on one of your project it will receive the data first then display that particular page.

First you have to modify your dataFactory something like this

app.service('MyService', function($http) {
    var myData = null;

    var promise = promise || $http.get('data.json').success(function (data) {
      myData = data;
    });

    return {
      promise:promise,
      doStuff: function () {
          return myData
      }
    };
});

Then in your $routeProvider you could make route to resolve when your data is fetched (that is receives its promise) more over by using this method it wont make another data call if your data is stored.

app.config(function($routeProvider){
  $routeProvider
    .when('/',{controller:'MainCtrl',
    template:'<div>From MyService:<pre>{{data | json}}</pre></div>',
    resolve:{
      'MyServiceData':function(MyService){
        return MyService.promise;
      }
    }})
    .when('/b',{controller:'MainCtrl2',
    template:'<div>From MyServic2e:<pre>{{data | json}}</pre></div>',
    resolve:{
      'MyServiceData':function(MyService){
        return MyService.promise;
      }
    }})
  })

I've a made a working Plunker for demo. Fell free to ask any question regarding this.

Hope it helps.

when you refersh the page, the app module loads again wiping out all the stored vars. You can use sessionStorage or localStorage to maintain data.

When you store your data into service/ factory store it in to your browser's local storage too. So, when user refresh the page, you can check whether your local storage has the data or not. If there is data in your local storage just save these data into your service/ factory .

That's all !!!

If you are struggle to implement these things please update me, I can help you on the code also.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM