我有一个控制器从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;
})
})
答案 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
分配任何内容,并从任何控制器,指令,服务和大多数地方(例如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中拦截它。
将$ rootScope服务注入控制器A.
从控制器A广播消息和参数[s]:
$ rootScope。$ broadcast(&#39; userDefinedEvent&#39;,{parameterOne:&#39; stringValue&#39;});
在控制器B中拦截它并采取相应的行动:
$ scope。$ on(&#39; userDefinedEvent&#39;,function(event,data){ 的console.log(数据); });
希望它能帮到你。
干杯,卢卡