如何在angularjs中定义控制器内部的普通javascript函数

时间:2016-09-11 12:00:52

标签: javascript angularjs

下面有一段代码片段。

sample.js

(function() {
    /*global angular */
    'use strict';

    angular.module('myapp', ['spinner'])
       .controller('myCtrl', ['$scope', '$window', function ($scope, $window ) {

    $scope.methodname = function() {
            if(something){
                /* Doing some operations */
            }
    };
    /* Here I need to define the callme javascript function */

   function callme(response){
       /* If I call like this, I'm getting error in console. */
    }

    }]);  /* Controller ends here */

    /* Creating a new anonymous function to perform some operations */
    (function () {
    'use strict';


     /* Edited */
   code.util.myHTTP(url, function (response) {

             // Adding response to session storage
            callme(response);

             }, function () {
               // Removing from session storage
        });

        })();
     }());

在这里,我无法在角度控制器内部调用callme javascript函数。我在控制台中遇到错误,如

Uncaught ReferenceError: callme is not defined

有没有办法实现这个目标?

我需要在callme函数中使用一些控制器参数,如$ window,这就是我在控制器中定义callme函数的原因。

我已经在我的js文件中运行了如下面的函数

.run(function($rootScope, $log, $window) {
});

我的要求就像调用匿名函数,在加载时会有一些api响应,我需要调用一个方法来处理响应。因为这些控制器参数,我想在控制器内定义我的方法。有没有其他方法可以实现这个目标?

1 个答案:

答案 0 :(得分:0)

你的缩进遍布各地,是使这段代码难以理解的原因。这是你正确格式化的代码..

(function () {
  /*global angular */
  'use strict';

  angular.module('myapp', ['spinner'])
    .controller('myCtrl', ['$scope', '$window', function ($scope, $window) {
      $scope.methodname = function () {
        if (something) {
          /* Doing some operations */
        }
      };
      /* Here I need to define the callme javascript function */

      function callme (response) {
        /* If I call like this, I'm getting error in console. */

      }
    }]); /* Controller ends here */

  /* Creating a new anonymous function to perform some operations */
  (function () {
    'use strict';

    /* Edited */
    code.util.myHTTP(url, function (response) {

      // Adding response to session storage
      callme(response);
    }, function () {
      // Removing from session storage
    });
  })();
}());

这不起作用的原因是因为function声明悬挂到其作用域的顶部,但不存在于该作用域之外。如果我们删除了一些错误,那么这就是您的代码简化为:

(function() {
  function MyController($scope) {
    $scope.methodname = function() {}

    function callme(response) {
    }
  }

  (function() {
    callme()
  }())
}())

callme已悬挂,但仅限于MyController的顶部。该符号不在该范围之外,这就是您无法在嵌套范围内执行callme()的原因。

你在做什么似乎是反模式;即使你可以实现这一点,core.util.myHTTP也不会在Angular摘要周期内执行,所以你必须在控制器内调用$scope.$apply,这通常被认为是一件坏事。为什么不直接使用$http

然而,如果真的想要这样做(而你没有),你可以像这样定义你的函数:

(function() {
  function callme(response) { }

  function MyController($scope) {}

  (function() {
    ...
    callme()
  }())
}())

或者你可以使用指令(或组件,取决于你的角度版本)来处理这个......这就是应该怎么做。

function SpinnerCtrl($http) {
  this.$http = $http
}
SpinnerCtrl.$inject = ['$http']
SpinnerCtrl.onInit = function onInit() {
  var that = this
  return this.$http.get(url)
    .then(function (response) {
      // Store it in session storage, do whatever.
      // Presumably there's some data you want to make accessible to other parts of the app, so I assign it to the controller here
      that.response = response
    })
}

angular.module('myapp', ['spinner'])
  .component('spinner', {
    controller: SpinnerCtrl,
    template: '<h1>{{ $ctrl.response }}</h1>'
  })

// or

function SpinnerCtrl($scope, $http) {
  return $http.get(url).then(function (response) {
    $scope.response = response
  })
}

angular.module('myapp', ['spinner'])
  .directive('spinner', function () {
    return {
      controller: SpinnerCtrl,
      template: '<h1>{{ response }}</h1>'
    }
  })

请注意,实际上您应该将$ http调用移动到服务并在那里处理会话存储;会话存储事物是实现细节,使用它的组件/指令不应该关心。我只是为了简洁而没有这样做。