是否可以让一个控制器使用另一个控制器?
例如:
这个HTML文档只是打印MessageCtrl控制器在MessageCtrl .js文件中传递的消息。
<html xmlns:ng="http://angularjs.org/">
<head>
<meta charset="utf-8" />
<title>Inter Controller Communication</title>
</head>
<body>
<div ng:controller="MessageCtrl">
<p>{{message}}</p>
</div>
<!-- Angular Scripts -->
<script src="http://code.angularjs.org/angular-0.9.19.js" ng:autobind></script>
<script src="js/messageCtrl.js" type="text/javascript"></script>
</body>
</html>
控制器文件包含以下代码:
function MessageCtrl()
{
this.message = function() {
return "The current date is: " + new Date().toString();
};
}
它只是打印当前日期;
如果我要添加另一个控制器DateCtrl,它将日期以特定格式返回给MessageCtrl,将如何进行此操作?DI框架似乎与xmlhttprequest和访问服务有关。
如果你正在寻找触发和广播事件来共享数据或跨控制器调用函数,请查看这个链接:并通过zbynour检查答案(答案具有最大投票)。我引用了他的答案!!
如果firstCtrl的作用域是secondCtrl作用域的父作用域,你的代码应该通过在firstCtrl中用$broadcast替换$emit来工作:
function firstCtrl($scope){
$scope.$broadcast('someEvent', [1,2,3]);
}
function secondCtrl($scope){
$scope.$on('someEvent', function(event, mass) {console.log(mass)});
}
如果你的作用域之间没有父子关系,你可以将$rootScope注入到控制器中,并将事件广播到所有的子作用域(也就是secondCtrl)。
function firstCtrl($rootScope){
$rootScope.$broadcast('someEvent', [1,2,3]);
}
最后,当你需要从子控制器向上分派事件到作用域时,你可以使用$scope.$emit。如果firstCtrl作用域是secondCtrl作用域的父作用域:
function firstCtrl($scope){
$scope.$on('someEvent', function(event, data) { console.log(data); });
}
function secondCtrl($scope){
$scope.$emit('someEvent', [1,2,3]);
}
你可以使用AngularJS提供的$controller服务。
angular.module('app',[]).controller('DateCtrl', ['$scope', function($scope){
$scope.currentDate = function(){
return "The current date is: " + new Date().toString();
}
}]);
angular.module('app').controller('MessageCtrl', ['$scope', function($scope){
angular.extend(this, $controller('DateCtrl', {
$scope: $scope
}));
$scope.messageWithDate = function(message){
return "'"+ message + "', " + $scope.currentDate;
}
$scope.action2 = function(){
console.log('Overridden in ChildCtrl action2');
}
}]);
控制器之间有多种通信方式。
最好的可能是共享服务:
function FirstController(someDataService)
{
// use the data service, bind to template...
// or call methods on someDataService to send a request to server
}
function SecondController(someDataService)
{
// has a reference to the same instance of the service
// so if the service updates state for example, this controller knows about it
}
另一种方法是在作用域上释放事件:
function FirstController($scope)
{
$scope.$on('someEvent', function(event, args) {});
// another controller or even directive
}
function SecondController($scope)
{
$scope.$emit('someEvent', args);
}
在这两种情况下,您也可以与任何指令通信。
下面是一个与Angular JS无关的发布-订阅方法。
搜索参数控制器
//Note: Multiple entities publish the same event
regionButtonClicked: function ()
{
EM.fireEvent('onSearchParamSelectedEvent', 'region');
},
plantButtonClicked: function ()
{
EM.fireEvent('onSearchParamSelectedEvent', 'plant');
},
搜索选择控制器
//Note: It subscribes for the 'onSearchParamSelectedEvent' published by the Search Param Controller
localSubscribe: function () {
EM.on('onSearchParamSelectedEvent', this.loadChoicesView, this);
});
loadChoicesView: function (e) {
//Get the entity name from eData attribute which was set in the event manager
var entity = $(e.target).attr('eData');
console.log(entity);
currentSelectedEntity = entity;
if (entity == 'region') {
$('.getvalue').hide();
this.loadRegionsView();
this.collapseEntities();
}
else if (entity == 'plant') {
$('.getvalue').hide();
this.loadPlantsView();
this.collapseEntities();
}
});
事件管理器
myBase.EventManager = {
eventArray:new Array(),
on: function(event, handler, exchangeId) {
var idArray;
if (this.eventArray[event] == null) {
idArray = new Array();
} else {
idArray = this.eventArray[event];
}
idArray.push(exchangeId);
this.eventArray[event] = idArray;
//Binding using jQuery
$(exchangeId).bind(event, handler);
},
un: function(event, handler, exchangeId) {
if (this.eventArray[event] != null) {
var idArray = this.eventArray[event];
idArray.pop(exchangeId);
this.eventArray[event] = idArray;
$(exchangeId).unbind(event, handler);
}
},
fireEvent: function(event, info) {
var ids = this.eventArray[event];
for (idindex = 0; idindex < ids.length; idindex++) {
if (ids[idindex]) {
//Add attribute eData
$(ids[idindex]).attr('eData', info);
$(ids[idindex]).trigger(event);
}
}
}
};
全球
var EM = myBase.EventManager;
下面是两个控制器共享服务数据的单页示例:
<!doctype html>
<html ng-app="project">
<head>
<title>Angular: Service example</title>
<script src="http://code.angularjs.org/angular-1.0.1.js"></script>
<script>
var projectModule = angular.module('project',[]);
projectModule.factory('theService', function() {
return {
thing : {
x : 100
}
};
});
function FirstCtrl($scope, theService) {
$scope.thing = theService.thing;
$scope.name = "First Controller";
}
function SecondCtrl($scope, theService) {
$scope.someThing = theService.thing;
$scope.name = "Second Controller!";
}
</script>
</head>
<body>
<div ng-controller="FirstCtrl">
<h2>{{name}}</h2>
<input ng-model="thing.x"/>
</div>
<div ng-controller="SecondCtrl">
<h2>{{name}}</h2>
<input ng-model="someThing.x"/>
</div>
</body>
</html>
也在这里:https://gist.github.com/3595424