AngularJS. 如何从控制器组件的外部调用控制器函数

20 浏览
0 Comments

AngularJS. 如何从控制器组件的外部调用控制器函数

如何在网页的任何位置(控制器组件外面)调用在控制器下定义的函数?\n当我按下“获取”按钮时,它能够完美运行。但是我需要在控制器的外面调用它。逻辑是:默认情况下,我的div是隐藏的。在导航菜单的某个地方,我按下一个按钮,它应该显示我的div并执行“获取”函数。我应该如何实现这个?\n我的网页是:\n

  
  
  

\n我的js:\n

   function MyController($scope) {
      // 默认数据和结构
      $scope.data = {
        "firstname" : "Nicolas",
        "lastname" : "Cage"
      };
      $scope.get = function() {
        $.ajax({
           url: "/php/get_data.php?",
           type: "POST",
           timeout: 10000, // 10秒获取结果,否则错误。
           error:function() { alert("临时错误,请重试...");},
           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秒获取结果,否则错误。
        error:function() { alert("临时错误,请重试...");},
        complete: function(){ $.unblockUI();},
        beforeSend: function(){ $.blockUI()},
        success: function(data){ }
      });
    };
   }

0
0 Comments

在AngularJS中,有时候我们需要从控制器外部调用控制器的函数。然而,使用angular.element(document.getElementById('ID')).scope().get()这种方法在Angular 1.5.2版本中已经不起作用了。有人在评论中提到,这种方法在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()

对我来说,这种方法非常有效(即使在组件内部也可以使用)。除了“从Angular外部调用Angular的东西是不好的做法”这一点之外,还有其他不好的地方吗?在我的情况下,我无法避免这种做法。

感谢您的帮助,我已经寻找这个问题的解决方法很久了。

0
0 Comments

在这个例子中,问题是如何从控制器组件外部调用控制器函数。问题的原因是,使用非AngularJS的代码(onClick函数调用)来调用控制器函数。解决方法是通过使用$scope.apply()来手动更新视图数据,以确保控制器函数的调用能够正确反映在视图上。

具体的解决方法如下:

1. 在HTML中,使用ng-controller指令将控制器与特定的HTML元素关联起来。

2. 在控制器中,定义一个$scope.updateCustomRequest函数,该函数接受三个参数,并通过$scope.customParams对象更新视图数据。

3. 在JavaScript中,创建一个名为angularApp的AngularJS模块,并将其与ManagerApp应用程序关联起来。

4. 在JavaScript中,通过angularApp.controller函数创建一个名为ManagerCtrl的控制器,该控制器依赖于$scope服务。在控制器函数中,定义了$scope.customParams对象和$scope.updateCustomRequest函数。

5. 在JavaScript中,通过ajaxResultPost函数来从控制器组件外部调用控制器函数。在这个函数中,使用AngularJS的angular.element和scope.$apply()方法来获取控制器的作用域,并在其作用域中调用$scope.updateCustomRequest函数。

6. 在HTML中,通过onClick属性将ajaxResultPost函数与按钮的点击事件关联起来。

最后,问题的提出者还提到了如果不使用$scope.apply(),则无法正确更新视图数据的问题。这是因为在这个例子中,控制器函数是通过非AngularJS的代码调用的,所以需要手动调用$scope.apply()来确保视图数据的更新。

通过以上步骤,我们可以实现从控制器组件外部调用控制器函数,并正确更新视图数据。

0
0 Comments

在AngularJS中,如果想要从控制器外部调用控制器的函数,可以使用以下方法:

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

其中,`get()`是控制器中的一个函数。

如果你使用jQuery,还可以将`document.getElementById('yourControllerElementID')`替换为`$('#yourControllerElementID')`。

另外,如果你的函数会改变视图上的内容,你应该调用以下代码来应用这些变化:

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

还有一点需要注意的是,作用域在页面加载后才会初始化,所以在作用域外部调用方法时,应该在页面加载后进行。否则,你将无法访问到作用域。

更新:

在最新的Angular版本中,你应该使用以下代码:

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

但是,这实际上是一种不好的做法,但有时你只是需要快速解决问题。

这似乎是一种代码异味,因为Angular的理念是不将DOM代码与Angular代码混合在一起...

所以,如果你不应该将DOM代码与Angular代码混合在一起,如果你希望在Angular控制器中的变量发生变化时触发某些jQuery动画,你应该如何清洁地做到这一点呢?

我无法让`$apply`部分对我起作用,直到我将代码包装成一个函数,例如:`..scope.$apply(function() { scope.get() });`

这很可能与当时使用的Angular版本非常旧有关。

实际上,我可以通过以下方式访问控制器:`angular.element(document.getElementById('yourControllerElementID')).scope().controller;`。例如,如果使用:`angular.element(document.getElementById('controller')).scope().get()`会抛出一个未定义的错误,但是如果使用`angular.element(document.getElementById('controller')).scope().controller.get()`就可以正常工作。

你可以直接使用控制器的名称来查找元素,像这样:`angular.element($("[ng-controller='MyController']"))`。这与DOM没有关联,应该可以消除代码异味。

或者如果你只有一个控制器,你可以这样写更通用的代码:`angular.element(document.querySelector('[ng-controller]')).scope()`

这个解决方法在Angular 1.4.9中是否可行?我无法访问`angular.element(...)`中的`scope()`,因为它返回`undefined`,而且`angular`元素/对象的`vardump`显示`scope`函数位于`__proto__`对象内。

是的,这绝对是一种代码异味,但是如果你需要使用插件扩展现有的软件产品,并且现有的软件产品本身不使用AngularJS,这将非常有用。

在生产环境中不能使用这个方法。`element.scope()`只在启用了debugInfo时才有效,而在生产环境中应该禁用debugInfo。请参考[文档](https://docs.angularjs.org/guide/production#disabling-debug-data)。

在最新版本的Angular中,你可以使用以下代码:

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

如果控制器位于组件内部,使用AngularJS v1.5.8应该如何做到这一点呢?

旧版本和更新的版本,两种解决方法在AngularJS版本1.6.4上都不起作用。是否有其他不同的方法或解决方案适用于AngularJS版本1.6.4?

0