指令控制器中其他控制器的调用方法

我有一个指令,它有自己的控制器。参见下面的代码:

var popdown = angular.module('xModules',[]);


popdown.directive('popdown', function () {
var PopdownController = function ($scope) {
this.scope = $scope;
}


PopdownController.prototype = {
show:function (message, type) {
this.scope.message = message;
this.scope.type = type;
},


hide:function () {
this.scope.message = '';
this.scope.type = '';
}
}


var linkFn = function (scope, lElement, attrs, controller) {


};


return {
controller: PopdownController,
link: linkFn,
replace: true,
templateUrl: './partials/modules/popdown.html'
}


});

这是一个错误/通知/警告的通知系统。我要做的是从另一个控制器(不是指令控制器)调用这个控制器上的函数 show。当我这样做时,我还希望我的 link 函数能够检测到一些属性发生了变化,并执行一些动画。

这里有一些代码来说明我的要求:

var app = angular.module('app', ['RestService']);


app.controller('IndexController', function($scope, RestService) {
var result = RestService.query();


if(result.error) {
popdown.notify(error.message, 'error');
}
});

因此,当在 popdown指令控制器上调用 show时,链接函数也应该被触发并执行动画。我怎么才能做到呢?

100829 次浏览

这是一个有趣的问题,我开始思考如何实现这样的东西。

我想出了 这个(小提琴)

基本上,我没有尝试从控制器调用指令,而是创建了一个模块来容纳所有的下拉逻辑:

var PopdownModule = angular.module('Popdown', []);

我在模块中放入了两样东西,一个是可以在任何地方注入的 API 的 factory,另一个是定义实际 popdown 元素行为的 directive:

工厂只定义了两个函数 successerror,并跟踪了几个变量:

PopdownModule.factory('PopdownAPI', function() {
return {
status: null,
message: null,
success: function(msg) {
this.status = 'success';
this.message = msg;
},
error: function(msg) {
this.status = 'error';
this.message = msg;
},
clear: function() {
this.status = null;
this.message = null;
}
}
});

这个指令将 API 注入到它的控制器中,并观察 API 的变化(为了方便起见,我使用 bootstrap css) :

PopdownModule.directive('popdown', function() {
return {
restrict: 'E',
scope: {},
replace: true,
controller: function($scope, PopdownAPI) {
$scope.show = false;
$scope.api = PopdownAPI;


$scope.$watch('api.status', toggledisplay)
$scope.$watch('api.message', toggledisplay)


$scope.hide = function() {
$scope.show = false;
$scope.api.clear();
};


function toggledisplay() {
$scope.show = !!($scope.api.status && $scope.api.message);
}
},
template: '<div class="alert alert-\{\{api.status}}" ng-show="show">' +
'  <button type="button" class="close" ng-click="hide()">&times;</button>' +
'  \{\{api.message}}' +
'</div>'
}
})

然后我定义了一个依赖于 Popdownapp模块:

var app = angular.module('app', ['Popdown']);


app.controller('main', function($scope, PopdownAPI) {
$scope.success = function(msg) { PopdownAPI.success(msg); }
$scope.error   = function(msg) { PopdownAPI.error(msg); }
});

HTML 看起来是这样的:

<html ng-app="app">
<body ng-controller="main">
<popdown></popdown>
<a class="btn" ng-click="success('I am a success!')">Succeed</a>
<a class="btn" ng-click="error('Alas, I am a failure!')">Fail</a>
</body>
</html>

我不确定这是否完全理想,但它似乎是一个合理的方式来建立一个全球化的弹出式指令沟通。

再说一次,作为参考,小提琴

您还可以将指令的控制器公开给父作用域,就像 ngForm使用 name属性所做的那样: http://docs.angularjs.org/api/ng.directive:ngForm

Here you could find a very basic example how it could be achieved http://plnkr.co/edit/Ps8OXrfpnePFvvdFgYJf?p=preview

在这个例子中,我使用 $clear方法(类似于指令的非常简单的公共 API)获得了带有专用控制器的 myDirective。我可以将此控制器发布到父范围,并在指令之外使用调用此方法。

我有更好的解决办法。

here is my directive , I have injected on object reference in directive and has extend that by adding invoke function in directive code .

app.directive('myDirective', function () {
return {
restrict: 'E',
scope: {
/*The object that passed from the cntroller*/
objectToInject: '=',
},
templateUrl: 'templates/myTemplate.html',


link: function ($scope, element, attrs) {
/*This method will be called whet the 'objectToInject' value is changes*/
$scope.$watch('objectToInject', function (value) {
/*Checking if the given value is not undefined*/
if(value){
$scope.Obj = value;
/*Injecting the Method*/
$scope.Obj.invoke = function(){
//Do something
}
}
});
}
};
});

使用参数在 HTML 中声明指令:

<my-directive object-to-inject="injectedObject"></ my-directive>

我的主管:

app.controller("myController", ['$scope', function ($scope) {
// object must be empty initialize,so it can be appended
$scope.injectedObject = {};


// now i can directly calling invoke function from here
$scope.injectedObject.invoke();
}];