角状物如何从控制器组件外部调用控制器函数

如何从网页的任何位置(控制器组件之外)调用控制器下定义的函数?

当我按下“获取”按钮时,它工作得很好。但我需要从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){ }
});
};
}
380997 次浏览

这可能是值得考虑的,如果您的菜单没有任何相关的范围是正确的方式去。这不是真正的角度方式。

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

另一件需要考虑的事情是,如果你的菜单没有范围,如果你有多个路由,那么你所有的控制器都必须有自己的更新和获取功能。(假设您有多个控制器)

下面是一种从外部调用控制器函数的方法:

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

其中,get()是来自控制器的功能。

你可以换

document.getElementById('yourControllerElementID')`

$('#yourControllerElementID')

如果您使用的是jQuery.

此外,如果您的函数意味着更改视图上的任何内容,则应该调用

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

以应用更改。

您应该注意的另一件事是,范围是在页面加载后初始化的,因此从范围外调用方法应始终在页面加载后完成。否则你根本不会到达瞄准镜。

更新:

对于最新版本的Angular,您应该使用

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

是的,事实上,这是不好的做法,但有时你只是需要快速和肮脏的事情。

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

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


function ControllerZero($scope, mySharedService) {
$scope.thing = mySharedService.thing;

控制器零。$inject=['$scope ',' MySharedService '];

我曾经使用$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);
}
}

我向服务发送控制器中有哪些功能需要调用

我在网上找到了一个例子。

有人写了这段代码,而且运行得很好。

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 ;
}
}

我有多条路线和多个控制器,因此我无法获得可接受的工作答案。我发现将函数添加到窗口是可行的:

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(); }
}

解决方案 在Angular 1.5.2中,angular.element(document.getElementById('ID')).scope().get()停止为我工作。有人在评论中提到,这在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()

我是Ionic Framework的用户,我发现始终提供当前控制器的$scope的用户是:

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

我怀疑这可以被修改以适应大多数场景,而不考虑框架(或不),通过找到将针对仅在给定控制器实例期间可用的特定DOM元素的查询。

从控制器外部调用角度范围函数。

// Simply Use "Body" tag, Don't try/confuse using id/class.


var scope = angular.element('body').scope();
scope.$apply(function () {scope.YourAngularJSFunction()});