在angularjs工厂方法中添加事件侦听器无法按预期工作

时间:2016-01-05 10:46:30

标签: javascript angularjs

由于我不想进入这里的原因,我在工厂方法( serviceAFunction )中添加了一个事件列表器,而不是控制器。当我点击呼叫链后失败。我在浏览器控制台中获得了"Uncaught TypeError: this.serviceC is not a function"。我做错了什么?

我尝试了Prototype方法,并在下一个片段中显示,但没有再好运。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>My Angular App</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
  <script type="text/javascript">
      (function () {
          'use strict';
          function myFactory($http) {
              var service = {
                  serviceA: serviceAFunction,
                  serviceB: serviceBFunction,
                  serviceC: serviceCFunction,
                  serviceD: serviceDFunction,
                  callParams: {}
              };
              return service;
              function serviceAFunction() {
                  alert("From A service");
                  document.getElementById("myBtn").addEventListener("click", this.serviceB);
                  //document.getElementById("myBtn").addEventListener("click", function () { alert(1);});
                  //document.getElementById("myBtn").addEventListener("click", $scope.doSomeThing);
                  this.serviceB();
              }
              function serviceBFunction() {
                  alert("From B service");
                  // During click event the following call fails.
                  this.serviceC();
              }
              function serviceCFunction() {
                  alert("From C service");
                  this.serviceD();
              }
              function serviceDFunction() {
                  alert("From D service");
              }
          }
          function myController($scope, $controller, myFactory) {
              $scope.doSomeThing = function () {
                  myFactory.serviceA();
              };
              myFactory.serviceA();
          }
          angular.module('myApp', []);
          angular.module('myApp').factory('myFactory', myFactory);
          myFactory.$inject = ['$http'];
          angular.module('myApp').controller('myController', myController);
          myController.$inject = ['$scope', '$controller', 'myFactory'];

      }())
  </script>
</head>
<body>
<div data-ng-app="myApp">
  <div data-ng-controller="myController">
    <h1>Here we go...</h1>
    <div id='MyTrial'>
      <input id="myBtn" type="button" value="Click Me"  />
    </div>
  </div>
</div>
</body>
</html>

原型方法。这里也没有成功。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>My Angular App</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
  <script type="text/javascript">
      (function () {
          'use strict';
          function myFactory() {
              function Factory($scope) {
                  this.$scope = $scope;
              }
              Factory.prototype.serviceA = serviceAFunction;
              Factory.prototype.serviceB = serviceBFunction;
              Factory.prototype.serviceC = serviceCFunction;
              Factory.prototype.serviceD = serviceDFunction;
              return Factory;
              function serviceAFunction() {
                  alert("From A service");
                  document.getElementById("myBtn").addEventListener("click", this.$scope.newFactory.serviceB);
                  //document.getElementById("myBtn").addEventListener("click", function () { alert(1);});
                  //document.getElementById("myBtn").addEventListener("click", $scope.doSomeThing);
                  this.serviceB();
              }
              function serviceBFunction() {
                  alert("From B service");
                  // What ever I do here, during click event the following call fails.
                  this.$scope.newFactory.serviceC();
              }
              function serviceCFunction() {
                  alert("From C service");
                  this.$scope.newFactory.serviceD();
              }
              function serviceDFunction() {
                  alert("From D service");
              }
          }
          function myController($scope, $controller, myFactory) {

              $scope.doSomeThing = function () {
                  //myFactory.serviceA();
              };
              $scope.newFactory = new myFactory($scope);
              $scope.newFactory.serviceA();
          }
          angular.module('myApp', []);
          angular.module('myApp').factory('myFactory', myFactory);
          //myFactory.$inject = ['$scope'];
          angular.module('myApp').controller('myController', myController);
          myController.$inject = ['$scope', '$controller', 'myFactory'];
      }())
  </script>
</head>
<body>
<div data-ng-app="myApp">
  <div data-ng-controller="myController">
    <h1>Here we go...</h1>
    <div id='MyTrial'>
      <input id="myBtn" type="button" value="Click Me"  />
    </div>
  </div>
</div>
</body>
</html>

2 个答案:

答案 0 :(得分:1)

这似乎是一个javascript问题。

您必须像这样缓存父范围:

var self = this;
function serviceBFunction() {
    alert("From B service");
    // During click event the following call fails.
    self.serviceC();
}

答案 1 :(得分:0)

为什么要在Factory中执行jquery onclick功能?有没有必要。

如果您想通过按钮点击呼叫serviceB,请通过控制器调用此方法。

  

当你使用jquery onclick时,这里它将作为元素   那就是你实际上是想做$(元素)。因此,这将不会有角度工厂将保留的方法/变量的集合。

     

但在Angular场景中,这是不同的。因为你需要范围或   工厂绝望,然后在工厂做你的代码逻辑   而不是jquery onclick功能。

<head>
  <title>My Angular App</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
  <script type="text/javascript">
      (function () {
          'use strict';
          function myFactory($http) {
              var service = {
                  serviceA: serviceAFunction,
                  serviceB: serviceBFunction,
                  serviceC: serviceCFunction,
                  serviceD: serviceDFunction,
                  callParams: {}
              };
              return service;
              function serviceAFunction() {
                  alert("From A service");
                
                 // document.getElementById("myBtn").addEventListener("click", this.serviceB);
                  //document.getElementById("myBtn").addEventListener("click", function () { alert(1);});
                  //document.getElementById("myBtn").addEventListener("click", $scope.doSomeThing);
                  this.serviceB();
              }
              function serviceBFunction() {
                  alert("From B service");
                  // During click event the following call fails.
                  this.serviceC();
              }
              function serviceCFunction() {
                  alert("From C service");
                  this.serviceD();
              }
              function serviceDFunction() {
                  alert("From D service");
              }
          }
          function myController($scope, $controller, myFactory) {
              $scope.doSomeThing = function () {
                  myFactory.serviceB();
              };
              myFactory.serviceA();
          }
          angular.module('myApp', []);
          angular.module('myApp').factory('myFactory', myFactory);
          myFactory.$inject = ['$http'];
          angular.module('myApp').controller('myController', myController);
          myController.$inject = ['$scope', '$controller', 'myFactory'];

      }())
  </script>
</head>
<body>
<div data-ng-app="myApp">
  <div data-ng-controller="myController">
    <h1>Here we go...</h1>
    <div id='MyTrial'>
      <input id="myBtn" type="button" ng-click="doSomeThing()" value="Click Me"  />
    </div>
  </div>
</div>
</body>