Passing data from one controller to other Angular

2019-08-02 01:01发布

I have a controller which is fetching an XML file using $http and parsing it into a json object. This is 'MainCtrl'. Now I want to get the same json object in other controllers without again going through an $http because I have already loaded the XML.

Here is my first controller

angularXML.controller('MainCtrl', ['$scope', '$http','courseDefService', function($scope, $http, courseDefService) {
    $http.get(base_url + 'assets/js/angularxml/courseDef.xml').then(function(response) {
    var chapters = [];
    var courseDef = x2js.xml_str2json(response.data);
    console.log(courseDef);
}

And here is my second controller

angularXML.controller('chapterCtrl', ['$scope', '$routeParams', function($scope, $routeParams) {
$scope.chapterNumber = $routeParams.id;
var chapter = $scope.chapterNumber - 1; /* index starts from zero */
}

I think I need to use factory. But I am not sure how to do that. I tried one implementation where I was fetching the XML inside the factory. But when I was calling the factory method, it was doing another ajax request which I confirmed through console.

Please help.

3条回答
来,给爷笑一个
2楼-- · 2019-08-02 01:25

Its not a best practice to make the XHR call within the controller. Separate it out in a factory and take care not to repeate the call If you have data available. Your service should have a full control over when to hit the server to fetch data. Controllers should only access the service.

I would probably do this:

App.factory('eywa', ['$http', function($http) {
  var eywaFactory = {};

  eywaFactory.data = '';
  eywaFactory.load = function() {
    this.data = $http.get('./assets/js/angularxml/courseDef.xml').then(function(data) {
      return x2js.xml_str2json(data);
    });
    return this.data;
  };

  eywaFactory.get = function() {
    return this.data === '' ? this.load() : this.data;
  };

  return eywaFactory;
}]);

And call the service inside controller:

App.controller('MainCtrl', function($scope, eywa) { 
    eywa.get().then(function(data) {
      $scope.courseDef = data;
    });
});
查看更多
Lonely孤独者°
3楼-- · 2019-08-02 01:33

Here is another quick and dirty approach: http://jsfiddle.net/cAY2N/

Basically, each controller has a reference to some variables in a service. Whenever the serivce's data changes, the changes are reflected automatically in all the controllers.

var app = angular.module('centralizedData', []);

app.service('CentralService', function($q, $timeout) {
    var self  = this,
        count = 0
        ;

    this.centralData = {};

    this.getData = function() {
        $timeout(function() {
            self.centralData.message = 'Hello: ' + count++;
        });
    };
});

app.controller('FirstController', function($scope, CentralService) { 
    $scope.data = CentralService.centralData;   
    CentralService.getData();
});

app.controller('SecondController', function($scope, CentralService) {
    $scope.data = CentralService.centralData;
    setTimeout(CentralService.getData, 2000);
});
查看更多
看我几分像从前
4楼-- · 2019-08-02 01:46

What about creating some kind of a message bus in your app?

First, create a MessageBus service:

module.factory("MessageBus", function($rootScope) {
    return {
        broadcast : function(event, data) {
            $rootScope.$broadcast(event, data);
        }
    };
});

Then, inject it to the originator controller:

function OriginatorController($scope, MessageBus) {
    $scope.funct = function(e) {
        // get data
        MessageBus.broadcast("data", data);
    };
};

And subscribe to events anywhere you want:

$scope.$on("data", function(arguments) {
    console.log(arguments);
});

You can even use $rootScope directly via DI and call $broadcast on it in your controllers, but creating a service is more expressive.

EDIT: Here is a pen for you.

查看更多
登录 后发表回答