I have a controller like this:
我有一个像这样的控制器:
function MyCtrl($scope) {
$scope.doSomething = function(){
alert("Do something!");
}
}
And I have multiple views which depend on this (ie multiple of the below):
我有多个视图依赖于此(即下面的多个):
<div ng-controller="MyCtrl">
...
</div>
The problem is, the data the controller depends on needs to be loaded in the background (the controller does not load that data), and a callback (dataIsReady()) will be called after the data is ready.
问题是,控制器依赖的数据需要在后台加载(控制器不加载该数据),并在数据准备好后调用回调(dataIsReady())。
function dataIsReady(){
// TODO: call the doSomething() function
}
Now, I want to basically call the doSomething() function, which is inside MyCtrl, from the dataIsReady() function. How can I do that?
现在,我想从dataIsReady()函数中调用doSomething()函数,该函数位于MyCtrl中。我怎样才能做到这一点?
2 个解决方案
#1
4
I think what you need is a data service, which you can then inject into your controller. You can call a function on your data service which will handle the retrieval of the data and return a "promise" which can then be used to trigger your callback function when the data has loaded. Have a look at the following code which is a slightly modified version from egghead.io:
我认为你需要的是一个数据服务,然后你可以将其注入你的控制器。您可以在数据服务上调用一个函数来处理数据检索并返回一个“promise”,然后可以在加载数据时触发回调函数。看看下面的代码,它是egghead.io的一个稍微修改过的版本:
Plunker Demo (w/ local storage): http://plnkr.co/edit/9w2jTg?p=preview
Plunker演示(带本地存储):http://plnkr.co/edit/9w2jTg?p = preview
var myApp = angular.module('myApp', []);
myApp.factory('AvengersService', function ($http) {
var AvengersService = {
getAsyncCast: function () {
// $http returns a promise, which has a then function, which also returns a promise
var promise = $http.get("avengers.json") // or some JSON service
.then(function (response) {
// The 'then' function here is an opportunity to modify the response
// The return value gets picked up by the 'then' in the controller.
return response.data;
});
// Return the promise to the controller
return promise;
}
};
return AvengersService;
});
myApp.controller('AvengersCtrl', function($scope, AvengersService) {
// Call the async method and then do something when the data is retrieved
AvengersService.getAsyncCast()
.then(function (asyncData) {
// Callback logic that depends on the data goes in here
console.info("Cast pulled async.");
$scope.avengers.cast = asyncData;
});
});
Hope that helps.
希望有所帮助。
#2
2
Notice: This approach in this answer is terribly wrong, one should not access to the scope of a controller outside of angular, or outside of controller at all. This would also be terribly slow if you try to call it several times. Other than that, it is fine. I am giving this answer because it is also the simplest way. I would never use that kind of code in production, though. The appropriate way is to write a service to communicate with the controller.
注意:这个方法在这个答案中是非常错误的,不应该在角度之外或控制器之外访问控制器的范围。如果您尝试多次调用它,这也会非常慢。除此之外,没关系。我给出了这个答案,因为它也是最简单的方法。但是我永远不会在生产中使用那种代码。适当的方法是编写服务以与控制器通信。
Given that you have defined $scope.doSomething
in MyCtrl
:
鉴于您已在MyCtrl中定义$ scope.doSomething:
var scp = angular.element('[ng-controller="MyCtrl"]').scope();
scp.doSomething();
Will call doSomething
method defined in the controller.
将调用控制器中定义的doSomething方法。
#1
4
I think what you need is a data service, which you can then inject into your controller. You can call a function on your data service which will handle the retrieval of the data and return a "promise" which can then be used to trigger your callback function when the data has loaded. Have a look at the following code which is a slightly modified version from egghead.io:
我认为你需要的是一个数据服务,然后你可以将其注入你的控制器。您可以在数据服务上调用一个函数来处理数据检索并返回一个“promise”,然后可以在加载数据时触发回调函数。看看下面的代码,它是egghead.io的一个稍微修改过的版本:
Plunker Demo (w/ local storage): http://plnkr.co/edit/9w2jTg?p=preview
Plunker演示(带本地存储):http://plnkr.co/edit/9w2jTg?p = preview
var myApp = angular.module('myApp', []);
myApp.factory('AvengersService', function ($http) {
var AvengersService = {
getAsyncCast: function () {
// $http returns a promise, which has a then function, which also returns a promise
var promise = $http.get("avengers.json") // or some JSON service
.then(function (response) {
// The 'then' function here is an opportunity to modify the response
// The return value gets picked up by the 'then' in the controller.
return response.data;
});
// Return the promise to the controller
return promise;
}
};
return AvengersService;
});
myApp.controller('AvengersCtrl', function($scope, AvengersService) {
// Call the async method and then do something when the data is retrieved
AvengersService.getAsyncCast()
.then(function (asyncData) {
// Callback logic that depends on the data goes in here
console.info("Cast pulled async.");
$scope.avengers.cast = asyncData;
});
});
Hope that helps.
希望有所帮助。
#2
2
Notice: This approach in this answer is terribly wrong, one should not access to the scope of a controller outside of angular, or outside of controller at all. This would also be terribly slow if you try to call it several times. Other than that, it is fine. I am giving this answer because it is also the simplest way. I would never use that kind of code in production, though. The appropriate way is to write a service to communicate with the controller.
注意:这个方法在这个答案中是非常错误的,不应该在角度之外或控制器之外访问控制器的范围。如果您尝试多次调用它,这也会非常慢。除此之外,没关系。我给出了这个答案,因为它也是最简单的方法。但是我永远不会在生产中使用那种代码。适当的方法是编写服务以与控制器通信。
Given that you have defined $scope.doSomething
in MyCtrl
:
鉴于您已在MyCtrl中定义$ scope.doSomething:
var scp = angular.element('[ng-controller="MyCtrl"]').scope();
scp.doSomething();
Will call doSomething
method defined in the controller.
将调用控制器中定义的doSomething方法。