2015-02-23 48 views
2

在下面的代码中,我创建了一个包含服务和控制器的模块。该服务包含我在控制器内共享和调用的单一方法。下面这段代码代表工作实现:AngularJS:在控制器方法内引发事件以调用服务方法

!(function() { 
     'use strict'; 

     var app = angular.module('app', []); 

     app.service('rootService', function() { 
     this.exampleFunction = function() { 
      alert('this is running from the service'); 
     }; 
     }); 

     app.controller('MainCtrl', ['$scope', 'rootService', 
     function($scope, rootService) { 
      rootService.exampleFunction(); 
     }]); 
    })(); 

这是我的问题:

我想调用只有当事件被触发控制器中的方法。当我为点击事件添加一个侦听器并且触发一个调用相同方法的函数时,错误控制台将返回:“Uncaught TypeError:undefined不是函数。”

这里是我试图代码:

!(function() { 
    'use strict'; 

    var app = angular.module('app', []); 

    app.service('rootService', function() { 
    this.exampleFunction = function() { 
     alert('this is running from the service'); 
    }; 
    }); 

    app.controller('MainCtrl', ['$scope', 'rootService', 
    function($scope, rootService) { 

     var button = document.getElementByTag(button); 
     button.addEventListener('click', function(rootService) { 
     rootService.exampleFunction(); 
     }); 
    } 
    ]); 
})(); 

为什么不这项工作?这两种实现之间有什么很大的变化?

回答

2

嗯,具体回答你的问题,问题是否是正确的方式,当你将点击处理程序附加到任何东西,当它触发时,它会收到一个Event对象,而不是rootService

Event没有方法exampleFunction,所以你得到你的未定义的消息。

对您而言,一种可能的解决方法是定义模板中的点击处理程序。

<button ng-click="callExampleFunction()">Click</button> 

并改变你的控制器。

app.controller('MainCtrl', ['$scope', 'rootService', 
    function($scope, rootService) { 
     $scope.callExampleFunction = function(){ 
      rootService.exampleFunction(); 
     }); 
    } 
    ]); 

此外,我想指出未来的读者,问题代码中有另一个错误。

var button = document.getElementByTag(button); 

该声明不起作用;文件有一个getElementsByTagName方法,而不是getElementByTaggetElementsByTagName采用字符串参数,并返回一个数组,所以校正后的代码(以找到第一个按钮)将是

var button = document.getElementsByTagName("button")[0]; 

最后,在角上,单击处理程序很容易用ng-click处理。如果您确实需要附加点击处理程序而不使用ng-click,则最好使用angular.element来执行指令。

angular.element("button").on("click", function(){...}) 
+0

谢谢你的回应。我实际在我的应用程序中侦听的事件是窗口大小调整。我会使用一个指令吗,就像@Josh Beam建议的那样? – shmuli 2015-02-23 04:09:36

+0

@shmuli是的,在这种情况下,指令可能更合适。谷歌搜索窗口调整大小指令会给你一些快速的例子。 – Bert 2015-02-23 04:12:34

+0

为什么这与在调用** local **方法的控制器中编写事件侦听器有所不同?这工作没有问题......只有当我尝试从控制器中的**服务**调用方法时,我遇到了问题,我无法使用事件侦听器执行此操作。 – shmuli 2015-02-23 04:43:28

1

addEventListener回调发生在全局上下文中,而不是在您的控制器上下文中。

这就是为什么建议您使用DOM操作,事件等指令的原因。AngularJS的基础是关注点的分离,并且您可能会遇到问题,如您构建的问题应用程序的方式与模块化原则相冲突。

编辑

我使用一个明确的用户自定义指令的建议,而是一个ng-click引用在控制器的功能将成为一个类似的目的。

1

有两个不同的空间,当我们使用angular,即angular-spacenon-angular-space。诸如addEventListener和所有jQuery听众的浏览器事件都属于non-angular-space,因此收听者将无法在angular-space中工作。几乎所有的浏览器事件都有等效的监听器指令,我们必须改用这些指令。在这种情况下,指令是ng-click

希望它是有道理的。

相关问题