将View中的变量传递给另一个控制器AngularJS

时间:2014-08-25 21:01:53

标签: json facebook angularjs ionic-framework

我有一个控制器从facebook api获取带有相册的对象。

.controller('GalleryCtrl', function($scope, $http) {
    $http.get('https://graph.facebook.com/v2.0/130180763686565/albums?fields=id,type,name,cover_photo,description&access_token=TOKEN').
        success(function(datos) {
            $scope.galleries = datos.data;
        })

})

在我看来,我这样打印,

<div ng-app="faceBook">
<div class="list" ng-repeat="gallery in galleries" ng-if="gallery.type=='normal'">

    <a class="item item-thumbnail-left" href="#/app/gallery/{{gallery.id}}" ng-click="$rootScope.albumId = {{gallery.id}}">
        <img src="https://graph.facebook.com/{{gallery.id}}/picture?type=album">
        <h2>{{gallery.name}}</h2>
        <p>{{gallery.description}}</p>
    </a>

</div>

我需要的是为每个相册指定对象的ID(gallery.id)并将其发送到下一个控制器,以便能够下载该相册的图片。

将gallery.id发送到此控制器,将hte varible放在下面显示的http.get中,其中albumId是。

如何将点击的项目的变量从第一个控制器发送到第二个?

这是我的单一相册控制器

.controller('AlbumCtrl', function($scope, $http) {
    $http.get('https://graph.facebook.com/v2.0/'+albumId+'/photos?fields=id&access_token=TOKEN').
        success(function(datos) {
            $scope.albums = datos.data;
        })

})

4 个答案:

答案 0 :(得分:14)

关于如何做到这一点有不同的意见,因为有几种方法。让我简要介绍一下它们。我主要使用服务,然后是$ rootScope,最后是事件。

使用服务

服务是可以使用Angular的依赖注入传递的Javascript对象。就像您可以在控制器中请求$ http一样,您可以创建一个能够在DI工作的任何地方存在的服务。这是最好的方法(IMO),因为您将数据隔离到服务中并且能够使用DI轻松传递它。该对象不必仅包含数据,它可以具有可以减少代码重复的方法。我能想到的唯一不利的是创建一个新文件。

此示例并非理想或适用于所有情况,您应根据需要进行调整。此示例仅能够在首次注入服务时加载一次相册,并存储要使用的数据。通常我会制作更复杂的服务来管理数据,因此我的控制器不必操纵我的模型。

<强>服务

angular.module('App').factory('AlbumService', function ($http) {

  var AlbumService;

  // Make our $http request and assign response to service
  $http.get('https://graph.facebook.com/v2.0/1234567890/albums?fields=id,type,name,cover_photo,description&access_token=TOKEN')
    .success(function(response) {
      AlbumService = response.data;
    });
  };

  return AlbumService;
});

控制器1

angular.module('App').controller('OneCtrl', function ($scope, AlbumService) {
  // Assume this runs first, it will create the service and make the http 
  // request and be made available to the $scope
  $scope.albums = AlbumService;
});

控制器2

angular.module('App').controller('TwoCtrl', function ($scope, AlbumService) {
  // Assume this runs second, it will return the same data from above. 
  // Even if it runs first, the result is the same because the first to inject 
  // the AlbumService will execute the $http request once and reuse the data
  console.log(AlbumService); 
});

使用$ rootScope共享

您可以为$rootScope分配任何内容,并从任何控制器,指令,服务和大多数地方(例如app.config之类的一些例外)进行操作。这很方便,只需要很少的开销。另一方面,它有点滥用你的$ rootScope,如果碰巧在其他地方的$ scope上使用相同的属性名,你可能会无意中丢失或覆盖值。

控制器1

angular.module('App').controller('OneCtrl', function ($rootScope, $http) {
  $http.get('https://graph.facebook.com/v2.0/1234567890/albums?fields=id,type,name,cover_photo,description&access_token=TOKEN')
    .success(function(response) {
      $rootScope.items = response.data;
    });
});

控制器2

angular.module('App').controller('TwoCtrl', function ($scope) {
  // will log out the values from response.data above, since its not on 
  // $scope it travels up the scope tree until the $rootScope. 
  console.log($scope.items); 
});

自定义活动

您可以使用事件来广播(在范围树下)或发出(在范围树上)数据。它在概念上与在使用JavaScript之前收听domready事件的想法相同。好处是您不使用$rootScope,并且您可以控制是否在范围树中向上或向下发送数据(取决于需要了解的有关此数据的范围)。另一方面,事件可能很棘手,导致因果关系混淆,并在应用程序的各个部分之间创建依赖关系,这使得难以维护。在这个例子中,两个控制器也必须在$ broadcast和$ on的同一页面中才能激活。

意见:在大多数情况下我会避免这种做法。可能有效的一个示例是,如果您有一个自定义指令控制外部库(例如图表),则需要触发图表以在事件发生时进行更改。当你需要事件驱动时我会使用它,这与关于如何访问不同控制器中的数据的原始问题不同(我称之为模型驱动)。

控制器1

angular.module('App').controller('OneCtrl', function ($rootScope, $http) {
  // This will broadcast this event down through every scope from the top
  $http.get('https://graph.facebook.com/v2.0/1234567890/albums?fields=id,type,name,cover_photo,description&access_token=TOKEN')
    .success(function(response) {
      $rootScope.$broadcast('myCustomEvent', response.data);
    });
});

控制器2

angular.module('App').controller('TwoCtrl', function ($scope) {
  // will log out the value of response.data above when the $broadcast occurs
  $scope.$on('myCustomEvent', function (event, data) {
    console.log(data);
  }); 
});

答案 1 :(得分:5)

您应该提供有关您的问题的更多信息:

根据我的理解,这就是你要做的事。

将您的href调用更改为ng-href并删除ng-click。

此:

  <a class="item item-thumbnail-left" href="#/app/gallery/{{gallery.id}}" ng-click="$rootScope.albumId = {{gallery.id}}">

成为这个

<a class="item item-thumbnail-left" ng-href="/app/gallery/{{gallery.id}}">

在将处理视图的控制器中。假设您将其称为ViewAlbumCtrl。

.controller('ViewAlbumCtrl', function($scope, $http, $routeParams) {
    var theId = $routeParams.galleryId;
    //Your cool code
});

您配置路线的位置应该是:

.config(['$routeProvider', 
  function($routeProvider) {
    $routeProvider
      .when('/app/gallery/:galleryId', {
        templateUrl: '/path/to/your/view.html',
        controller: 'ViewAlbumCtrl'
      });
   }]);

希望它对你有所帮助。

答案 2 :(得分:1)

使用$ stateParams!

在您的app.js文件中

.state('app.single', {
url: "/clientes/:clienteId",
views: {
  'menuContent': {
    templateUrl: "views/cliente.html",
    controller: 'ClienteCtrl'
  }
}
})

在您的观点中:

<ion-item class="item-avatar" href="#/app/clientes/{{cliente.id}}" >

控制器:

angular.module('cobranza-mobile.controllers').
controller('ClienteCtrl', function ($scope, $stateParams) {
   alert($stateParams.clienteId);
});

答案 3 :(得分:0)

您可以从控制器A以$ rootScope级别发送消息,并在控制器B中拦截它。

  1. 将$ rootScope服务注入控制器A.

  2. 从控制器A广播消息和参数[s]:

    $ rootScope。$ broadcast(&#39; userDefinedEvent&#39;,{parameterOne:&#39; stringValue&#39;});

  3. 在控制器B中拦截它并采取相应的行动:

    $ scope。$ on(&#39; userDefinedEvent&#39;,function(event,data){   的console.log(数据); });

  4. 希望它能帮到你。

    干杯,卢卡

相关问题