在Angularjs

时间:2015-11-21 01:31:29

标签: javascript angularjs angular-controller

我是角色的新手,我正在努力了解如何使用服务将数据从一个控制器传递到另一个控制器。

到目前为止,使用Angular,我已经能够理解如何调用控制器并从HTML中将数据传递给它们。为了设置地图控制器,我一直特别好,我查看来自PHP的结果列表,并将这些结果中的数据发送到我的控制器,以在地图上创建标记。

让我完全难过的是,有一个控制器通过ElasticSearch调用生成嵌套对象,然后将该数据传递给我的Map Controller。

最初我尝试通过ng-repeat循环遍历结果,虽然我能够输出结果,但我的MapController无法在HTML中读取这些结果,因为它们在我的IndexController(这是输出数据)。我认为情况确实如此。

这是我尝试过的,虽然它输出了数据,但我无法在MapController中读取它。

<div ng-controller="IndexController">
    <div ng-repeat="r in listingsArea.results">
        <div class="component home-listings"
            data-id="{{r.id}}"
            data-url="{{r.url}}"
            data-lat="{{r.lat}}"
            data-lng="{{r.lon}}"
            data-address="{{r.address}}"
            data-price="{{r.price}}"
        ></div>
    </div>
</div>

我已经读过将数据从一个控制器传递到另一个控制器的最佳方法是通过服务。我在这里遵循了很多文档,但尽管如此,我显然错过了一些因为它不起作用的东西。

这就是我到目前为止:

ResultsService.js

App.factory("resultsService", function() {

var loadListingsArea = {};

return {
    getLocations: function() {
        return loadListingsArea
    },

    setLocations: function(loc) {
        loadListingsArea = loc;

IndexController.js

App.controller('IndexController', function($scope, resultsService) {

$scope.listingsArea = [];

$scope.loadListingsArea = function() {
    $http.get($window.location + '/listingsarea')
        .success(function(data) {
            $scope.listingsArea = data;
        }
    );
}

$scope.$watch(function() {
    return $scope.loadListingsArea;
}, function() {
    resultsService.setLocations($scope.loadListingsArea);
});
});

MapController.js (只是试图在此阶段转储对象,不包括我为google地图设置的代码库)

App.controller('MapController', function($scope, resultsService) {

$scope.locations = resultsService.getLocations();

alert($scope.locations);

这是从indexcontroller.js

转储时我的对象的样子
{"count":4,
"results":[
      {"id":"1153292",
       "url":"/this-is-my-slug/1153292",
       "lat":"-37.822034",
       "lon":"144.969553",
       "address":"1302/430 Place Road",
       "price":"$2,350,000",
       "hero":"some-image-here.jpg"}
]};

2 个答案:

答案 0 :(得分:1)

$http服务返回一个承诺。存储它。无需执行$q.defer内容。

App.factory("resultsService", function() {

  var self = this;
  self.listingsPromise = undefined;

  return {
      loadLocations: function(url) {
           self.listingPromise = $http.get(url);
           return self.listingPromise;
      },
      getLocations: function() {
        return self.listingPromise;
      }
  );
}

启动检索的控制器可以执行以下操作:

resultsService.loadLocations() // returns a promise
  .then(function(response){
    $scope.listingsArea = response.data;
  }) .catch ( function (error) {
    throw error;
  });

只需要获得它的控制器就可以做到这一点:

resultsService.getLocations()
  .then(function(response){
    $scope.listingsArea = response.data;
  }) .catch ( function(error) {
    throw error;
  });

请注意,两个控制器都需要检查错误。

另请注意,.then以不同于.success的方式返回数据。

AngularJS团队已经醒悟并弃用.success。从现在开始,我们都应该使用.then

有关弃用.success的信息以及更多信息,请参阅最新的AngularJS $http API Docs

答案 1 :(得分:0)

将$ http.get移动到您服务中的函数中。 编辑使用$ q.deferred而不是返回$ http的承诺。

App.factory("resultsService", function() {

  var self = this;
  self.deferred = $q.defer();
  self.listingsArea = {};

  return {
      loadLocations: function() {
          $http.get($window.location + '/listingsarea')
              .then(function(data){
                 self.listingsArea = data;
                 self.deferred.resolve(self.listingsArea);
              },
              function(e){
                self.deferred.reject(e);
              });
          return self.deferred.promise;
      },
      getLocations: function() {
        return self.deferred.promise;
      }
  );
}

启动检索的控制器可以执行以下操作:

resultsService.loadLocations() // returns a promise
  .then(function(data){
    $scope.listingsArea = data;
  });

只需要获得它的控制器就可以做到这一点:

resultsService.getLocations()
  .then(function(data){
    $scope.listingsArea = data;
  });

这可能需要一些额外的按摩,但它应该给你一个方向进入。

另请注意,以这种方式共享对象意味着您可以从任一控制器编辑同一对象。为避免这种情况,请改为传递数据对象的angular.copy。