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),只有在给定的控制器实例中可用的查询。