如何从网页的任何位置(控制器组件之外)调用控制器下定义的函数?
当我按下“获取”按钮时它完美运行。但我需要从div控制器外部调用它。逻辑是:默认情况下我的div是隐藏的。在导航菜单的某处我按下一个按钮,它应该显示()我的div并执行“get”功能。我怎么能做到这一点?
我的网页是:
<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){ }
});
};
}
答案 0 :(得分:321)
这是一种从外部调用控制器函数的方法:
angular.element(document.getElementById('yourControllerElementID')).scope().get();
其中get()
是您控制器的功能。
您可以切换
document.getElementById('yourControllerElementID')`
到
$('#yourControllerElementID')
如果您使用的是jQuery。
此外,如果您的功能意味着更改View上的任何内容,则应致电
angular.element(document.getElementById('yourControllerElementID')).scope().$apply();
应用更改。
还有一件事,你应该注意的是,在加载页面之后初始化作用域,因此在加载页面之后应该始终在作用域之外调用作用域。否则你根本不会进入范围。
<强>更新强>
使用最新版本的angular,您应该使用
angular.element(document.getElementById('yourControllerElementID')).injector().get('$rootScope')
是的,事实上,这是一种不好的做法,但有时候你只需要快速而又肮脏的事情。
答案 1 :(得分:36)
我在互联网上找到了一个例子。
有些人写了这段代码并且工作得很好
<强> 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);
});
}
*我做了一些修改,见原文:font JSfiddle
答案 2 :(得分:11)
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 ;
}
}
答案 3 :(得分:9)
解决方案
angular.element(document.getElementById('ID')).scope().get()
在角色1.5.2中停止为我工作。 Sombody在评论中提到这在1.4.9中也不起作用。
我通过将范围存储在全局变量中来修复它:
var scopeHolder;
angular.module('fooApp').controller('appCtrl', function ($scope) {
$scope = function bar(){
console.log("foo");
};
scopeHolder = $scope;
})
从自定义代码调用:
scopeHolder.bar()
如果您想将范围限制为仅此方法。尽量减少整个范围的暴露。使用以下技术。
var scopeHolder;
angular.module('fooApp').controller('appCtrl', function ($scope) {
$scope.bar = function(){
console.log("foo");
};
scopeHolder = $scope.bar;
})
从自定义代码调用:
scopeHolder()
答案 4 :(得分:7)
我宁愿将工厂作为依赖项包含在控制器上,而不是使用自己的代码行注入它们: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'];
答案 5 :(得分:5)
如果没有任何相关范围的菜单是正确的方法,可能值得考虑。它不是真正有棱有角的方式。
但是,如果这是你需要的方式,那么你可以通过将函数添加到$ rootScope然后在这些函数中使用$ broadcast来发送事件来实现。然后你的控制器使用$ on来监听这些事件。
如果最终确定没有示波器的菜单,另外要考虑的是,如果您有多个路径,那么所有控制器都必须拥有自己的upate和get函数。 (假设您有多个控制器)
答案 6 :(得分:4)
我习惯使用$ 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);
}
}
我向服务发送了必须在控制器中调用的函数
答案 7 :(得分:3)
我有多条路线和多个控制器,所以我无法获得接受的工作答案。我发现在窗口中添加函数有效:
EditText
然后在控制器外面,可以这样做:
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;
}
答案 8 :(得分:0)
我是一个Ionic框架用户,我发现它将始终如一地提供当前控制器的$ scope:
...
2444
18472
29912
25180
6612
29440
13220
4684
14004
12388
16424
26320
25948
28076
30904
6396
1160
4228
...
我怀疑通过查找将定位仅在给定控制器实例期间可用的特定DOM元素的查询,可以修改此问题以适应大多数情况,无论框架(或不是框架)。
答案 9 :(得分:0)
从控制器外部调用Angular Scope功能。
// Simply Use "Body" tag, Don't try/confuse using id/class.
var scope = angular.element('body').scope();
scope.$apply(function () {scope.YourAngularJSFunction()});