在 Angularjs 中的控制器之间传递对象
Passing object between controllers in Angularjs
我是 angular 的新手,正在努力了解如何使用服务将数据从一个控制器传递到另一个控制器。
到目前为止,通过 Angular,我已经能够理解如何从 HTML 中调用控制器并向它们传递数据。为了设置一个地图控制器,这特别好,我查看了来自 PHP 的结果列表,并将这些结果的数据发送到我的控制器,以在地图上创建标记。
让我完全难过的是,有一个控制器通过 ElasticSearch 调用生成嵌套对象,然后将该数据传递到我的地图控制器。
最初我尝试通过 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":",350,000",
"hero":"some-image-here.jpg"}
]};
将 $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。
$http
服务returns一个承诺。存储那个。无需执行 $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
returns 数据不同于 .success
。
AngularJS 团队已经意识到并弃用了 .success
。从现在开始我们都应该使用 .then
。
有关弃用 .success
的信息以及更多信息,请参阅最新的 AngularJS $http API Docs
我是 angular 的新手,正在努力了解如何使用服务将数据从一个控制器传递到另一个控制器。
到目前为止,通过 Angular,我已经能够理解如何从 HTML 中调用控制器并向它们传递数据。为了设置一个地图控制器,这特别好,我查看了来自 PHP 的结果列表,并将这些结果的数据发送到我的控制器,以在地图上创建标记。
让我完全难过的是,有一个控制器通过 ElasticSearch 调用生成嵌套对象,然后将该数据传递到我的地图控制器。
最初我尝试通过 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":",350,000",
"hero":"some-image-here.jpg"}
]};
将 $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。
$http
服务returns一个承诺。存储那个。无需执行 $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
returns 数据不同于 .success
。
AngularJS 团队已经意识到并弃用了 .success
。从现在开始我们都应该使用 .then
。
有关弃用 .success
的信息以及更多信息,请参阅最新的 AngularJS $http API Docs