AngularJS。 如何从控制器组件外部调用控制器function

如何从网页的任何地方(控制器组件外部)调用控制器下定义的函数?

当我按下“获取”button时,它完美的工作。 但是我需要从div控制器之外调用它。 逻辑是:默认情况下,我的div是隐藏的。 在导航菜单的某个地方,我按下一个button,它应该显示()我的div并执行“获取”function。 我怎么能做到这一点?

我的网页是:

<div ng-controller="MyController"> <input type="text" ng-model="data.firstname" required> <input type='text' ng-model="data.lastname" required> <form ng-submit="update()"><input type="submit" value="update"></form> <form ng-submit="get()"><input type="submit" value="get"></form> </div> 

我的js:

  function MyController($scope) { // default data and structure $scope.data = { "firstname" : "Nicolas", "lastname" : "Cage" }; $scope.get = function() { $.ajax({ url: "/php/get_data.php?", type: "POST", timeout: 10000, // 10 seconds for getting result, otherwise error. error:function() { alert("Temporary error. Please try again...");}, complete: function(){ $.unblockUI();}, beforeSend: function(){ $.blockUI()}, success: function(data){ json_answer = eval('(' + data + ')'); if (json_answer){ $scope.$apply(function () { $scope.data = json_answer; }); } } }); }; $scope.update = function() { $.ajax({ url: "/php/update_data.php?", type: "POST", data: $scope.data, timeout: 10000, // 10 seconds for getting result, otherwise error. error:function() { alert("Temporary error. Please try again...");}, complete: function(){ $.unblockUI();}, beforeSend: function(){ $.blockUI()}, success: function(data){ } }); }; } 

这是一种从外部调用控制器function的方法:

 angular.element(document.getElementById('yourControllerElementID')).scope().get(); 

get()是你的控制器的一个函数。

你可以切换

 document.getElementById('yourControllerElementID')` 

 $('#yourControllerElementID') 

如果你正在使用jQuery。

另外,如果你的function意味着改变你的视图的任何东西,你应该打电话

 angular.element(document.getElementById('yourControllerElementID')).scope().$apply(); 

应用更改。

还有一点,你应该注意的是范围在页面加载后被初始化,因此调用范围之外的方法应该总是在加载页面之后完成。 否则,你根本就不能进入范围。

更新:

有了angular度的最新版本,你应该使用

 angular.element(document.getElementById('yourControllerElementID')).injector().‌​get('$rootScope') 

是的,这实际上是一个不好的做法 ,但有时候你只需要快速而又肮脏的事情。

我在网上find了一个例子。

有些人写了这个代码,完美的工作

HTML

 <div ng-cloak ng-app="ManagerApp"> <div id="MainWrap" class="container" ng-controller="ManagerCtrl"> <span class="label label-info label-ext">Exposing Controller Function outside the module via onClick function call</span> <button onClick='ajaxResultPost("Update:Name:With:JOHN","accept",true);'>click me</button> <br/> <span class="label label-warning label-ext" ng-bind="customParams.data"></span> <br/> <span class="label label-warning label-ext" ng-bind="customParams.type"></span> <br/> <span class="label label-warning label-ext" ng-bind="customParams.res"></span> <br/> <input type="text" ng-model="sampletext" size="60"> <br/> </div> </div> 

JAVASCRIPT

 var angularApp = angular.module('ManagerApp', []); angularApp.controller('ManagerCtrl', ['$scope', function ($scope) { $scope.customParams = {}; $scope.updateCustomRequest = function (data, type, res) { $scope.customParams.data = data; $scope.customParams.type = type; $scope.customParams.res = res; $scope.sampletext = "input text: " + data; }; }]); function ajaxResultPost(data, type, res) { var scope = angular.element(document.getElementById("MainWrap")).scope(); scope.$apply(function () { scope.updateCustomRequest(data, type, res); }); } 

演示

*我做了一些修改,看到原始:字体JSfiddle

德米特里的答案正常。 我只是使用相同的技术做了一个简单的例子。

jsfiddle: http : //jsfiddle.net/o895a8n8/5/

 <button onclick="call()">Call Controller's method from outside</button> <div id="container" ng-app="" ng-controller="testController"> </div> 

 function call() { var scope = angular.element(document.getElementById('container')).scope(); scope.$apply(function(){ scope.msg = scope.msg + ' I am the newly addded message from the outside of the controller.'; }) alert(scope.returnHello()); } function testController($scope) { $scope.msg = "Hello from a controller method."; $scope.returnHello = function() { return $scope.msg ; } } 

我宁愿将工厂作为依赖关系包含在控制器中,而不是用自己的代码行注入: http : //jsfiddle.net/XqDxG/550/

 myModule.factory('mySharedService', function($rootScope) { return sharedService = {thing:"value"}; }); function ControllerZero($scope, mySharedService) { $scope.thing = mySharedService.thing; 

ControllerZero。$ inject = ['$ scope','mySharedService'];

如果让你的菜单没有任何关联的范围是正确的方法,可能值得考虑。 它不是真正的angular度的方式。

但是,如果这是您需要的方式,那么您可以通过将函数添加到$ rootScope,然后在使用$ broadcast的函数内发送事件来完成。 你的控制器然后使用$来听这些事件。

如果最终让菜单没有范围,另一个要考虑的事情是,如果你有多个路由,那么你所有的控制器将不得不有自己的upate和获得函数。 (这是假设你有多个控制器)

解决schemeangular.element(document.getElementById('ID')).scope().get()在angular1.5.2停止工作。 Sombody在评论中提到,这在1.4.9中也不起作用。 我通过将范围存储在一个全局variables中来解决它:

 var scopeHolder; angular.module('fooApp').controller('appCtrl', function ($scope) { $scope = function bar(){ console.log("foo"); }; scopeHolder = $scope; }) 

从自定义代码调用:

 scopeHolder.bar() 

如果你想限制范围只有这种方法。 尽量减less整个范围的暴露。 使用以下技术。

 var scopeHolder; angular.module('fooApp').controller('appCtrl', function ($scope) { $scope.bar = function(){ console.log("foo"); }; scopeHolder = $scope.bar; }) 

从自定义代码调用:

 scopeHolder() 

我用$ http来工作,当想从资源中获取一些信息时,我执行以下操作:

 angular.module('services.value', []) .service('Value', function($http, $q) { var URL = "http://localhost:8080/myWeb/rest/"; var valid = false; return { isValid: valid, getIsValid: function(callback){ return $http.get(URL + email+'/'+password, {cache: false}) .success(function(data){ if(data === 'true'){ valid = true; } }).then(callback); }} }); 

和控制器中的代码:

 angular.module('controllers.value', ['services.value']) .controller('ValueController', function($scope, Value) { $scope.obtainValue = function(){ Value.getIsValid(function(){$scope.printValue();}); } $scope.printValue = function(){ console.log("Do it, and value is " Value.isValid); } } 

我向控制器发送什么函数必须调用的服务

我有多个路线和多个控制器,所以我不能得到接受的答案工作。 我发现添加到窗口的function工作:

 fooModule.controller("fooViewModel", function ($scope, fooService, $http, $q, $routeParams, $window, $location, viewModelHelper, $interval) { $scope.initFoo = function () { // do angular stuff } var initialize = function () { $scope.initFoo(); } initialize(); window.fooreinit = initialize; } 

然后在控制器之外,可以这样做:

 function ElsewhereOnThePage() { if (typeof(fooreinit) == 'function') { fooreinit(); } } 

我是一个Ionic框架用户,我发现,将持续提供当前控制器的$范围是:

angular.element(document.querySelector('ion-view[nav-view="active"]')).scope()

我怀疑这可以被修改,以适应大多数情况下,无论框架(或不),通过查找将针对特定的DOM元素(s),只有在给定的控制器实例中可用的查询。