2013-08-09 3 views
1

У меня есть контроллер, который извлекает XML-файл с помощью $ http и анализирует его в json-объект. Это «MainCtrl». Теперь я хочу получить один и тот же объект json в других контроллерах, не перейдя через $ http, потому что я уже загрузил XML.Передача данных с одного контроллера на другой Угловой

Вот мой первый контроллер

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); 
} 

А вот мой второй контроллер

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

Я думаю, что нужно использовать завод. Но я не знаю, как это сделать. Я попробовал одну реализацию, где я собирал XML внутри фабрики. Но когда я вызывал фабричный метод, он делал еще один запрос ajax, который я подтвердил с помощью консоли.

Пожалуйста, помогите.

+0

возможно дубликат [Как я могу передавать переменные между контроллерами в AngularJS?] (HTTP: // stackoverflow.com/questions/12008908/how-can-i-pass-variables-between-controllers-in-angularjs) – zsong

ответ

2

Не самая лучшая практика для вызова XHR внутри контроллера. Отделите его на заводе и будьте осторожны, чтобы не повторить вызов. Если у вас имеются данные. Ваша служба должна иметь полный контроль над тем, когда нужно удалять сервер для получения данных. Контроллеры должны иметь доступ только к службе.

я бы, вероятно, сделать это:

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; 
}]); 

И вызовите службу внутри контроллера:

App.controller('MainCtrl', function($scope, eywa) { 
    eywa.get().then(function(data) { 
     $scope.courseDef = data; 
    }); 
}); 
+0

Позвольте мне попробовать этот метод. –

+0

Nop это не работает. Используя этот метод, я получаю $ scope.courseDef как неопределенный. –

+0

offcourse он должен работать. Я ошибся там в сервисе - эта информация должна быть собственностью eywaFactory. – codef0rmer

5

Как насчет создания какой-либо шины сообщений в вашем приложении?

Во-первых, создать MessageBus сервис:

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

Затем вводят его в контроллер отправителе:

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

И подписаться на события в любом месте вы хотите:

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

You может даже использовать $rootScope непосредственно через DI и позвонить $broadcast на нем в ваших контроллерах, но создание сервиса более выразительно.

EDIT: Here is a pen for you.

3

Вот еще один быстрый и грязный подход: http://jsfiddle.net/cAY2N/

В принципе, каждый контроллер имеет ссылку на некоторые переменные в службе. Всякий раз, когда данные serivce меняются, изменения автоматически отражаются во всех контроллерах.

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); 
}); 
+0

Как-то я не могу заставить это работать. Вот скрипка для того же. Напоминая вам снова, что я пытаюсь загрузить XML-файл внутри первого контроллера, а затем использовать его во втором. Http: // jsfiddle.net/Nv779/ –

+0

В этой скрипте вы по-прежнему выполняете независимые вызовы ajax в каждом контроллере, и вы не назначаете никаких переменных $ scope объекту «courseDef» в вашей службе CentralCourseDef. Поэтому, когда в вашей службе CentralCourseDev вызывается «getXML», ваши контроллеры понятия не имеют, что это произошло. Вам нужно будет подключить его, как мой jsFiddle, включив службу в качестве зависимости в каждом контроллере, а затем сделав некоторые задания. Подход $ rootScope от madhead может работать лучше в вашем случае. – Scott

Смежные вопросы