在 AngularJS 服务中使用 'this'

Using 'this' inside AngularJS services

请检查下面的代码。我编辑了一个弹出窗口的离子示例只是为了说明。

在 showAlert1() 上,我按原样引用 'this',但它不起作用。在 showAlert2() 上,我使用了一个接收 'this' 的辅助变量“_this”,它确实有效。

我在其他场合看到过这种情况,我认为这与'Controller as'语法范围有关,但为什么会发生这种情况?

angular.module('myApp', ['ionic'])
.controller('PopupCtrl',function($scope, $ionicPopup) {

   this.testAlert = function() {
     alert('Alerting!');
   };

   this.showAlert1 = function() {
     $ionicPopup.alert({
       title: 'Don\'t eat that!',
       template: 'It might taste good'
     }, this).then(function() {
       this.testAlert();
     });
   };

   this.showAlert2 = function() {
     var _this = this;
     $ionicPopup.alert({
       title: 'Don\'t eat that!',
       template: 'It might taste good'
     }, _this).then(function() {
       _this.testAlert();
     });
   };

});

这是一支代码笔:http://codepen.io/anon/pen/dPJVNN

谢谢!

关键字 'this' 指的是它所在的当前对象。因此在您的 showAlert1() 函数中,'this' 指的是 $ionicPopup 对象。

例如

var parent = {
    value: 'parent',
    alert: function(){
        alert(this.value);
    },
    child: {
        alert: function(){
            alert(this.value);
        }
    }
}

如果您执行 parent.alert(),它会提醒家长。但是如果你做一个 parent.child.alert() 它会给你未定义的,因为 'this.value' 不存在,它不引用 parent.value。那么这里的意思就是this指的是当前对象。

javascript 中的

"this" 与其他语言中的 "this" 不同。您可以将其更多地视为函数调用的上下文。

Web 应用程序的默认调用上下文是 window。但是,当调用作为对象的 属性 的函数时,上下文成为对象。

因此,在您的示例中:

angular.module('myApp', ['ionic'])
.controller('PopupCtrl',function($scope, $ionicPopup) {
   //"this" refers to the controller instance here (controllers are created by angular with the "new" operator)
   this.testAlert = function() {
     //inside of this function, "this" will still be the controller
     alert('Alerting!');
   };

   //"this" is the controller
   this.showAlert1 = function() {
   //"this" is still the controller
     $ionicPopup.alert({
       title: 'Don\'t eat that!',
       template: 'It might taste good'
     }, this).then(function() {
       //"this" is no longer the controller.  It's probably "window", but it's possible that ionic sets this to some other parameter when it invokes the function.
       //since it's not the controller, testAlert() is undefined!
       this.testAlert();
     });
   };

   //"this" is the controller
   this.showAlert2 = function() {
     //"this" is still the controller, and you have assigned _this to also be the controller
     var _this = this;
     $ionicPopup.alert({
       title: 'Don\'t eat that!',
       template: 'It might taste good'
     }, _this).then(function() {
       //"_this" is captured by the closure created by the function call, and it is still the controller, so testAlert() is defined. 
       _this.testAlert();
     });
   };

});

您会经常在代码中看到:

var self = this;

使用 "self" 代替它以避免您遇到的混淆。

angular.module('myApp', ['ionic'])
.controller('PopupCtrl',function($scope, $ionicPopup) {
   var self = this;
   self.testAlert = function() {
     alert('Alerting!');
   };

   self.showAlert1 = function() {
     $ionicPopup.alert({
       title: 'Don\'t eat that!',
       template: 'It might taste good'
     }, self).then(function() {
       self.testAlert();
     });
   };

   self.showAlert2 = function() {

     $ionicPopup.alert({
       title: 'Don\'t eat that!',
       template: 'It might taste good'
     }, self).then(function() {
       self.testAlert();
     });
   };

});
showAlert1 中的 .then() 回调中的

"this" 指的是全局对象。试试这个:

angular.module('mySuperApp', ['ionic'])
.controller('PopupCtrl',function($scope, $ionicPopup) {

   this.testAlert = function() {
     alert('Alerting!');
   };

   this.showAlert1 = function() {
     $ionicPopup.alert({
       title: 'Don\'t eat that!',
       template: 'It might taste good'
     }, this).then(function() {
       alert(this === window);
       this.testAlert();
     });
   };

   this.showAlert2 = function() {
     var _this = this;
     $ionicPopup.alert({
       title: 'Don\'t eat that!',
       template: 'It might taste good'
     }, _this).then(function() {
       _this.testAlert();
     });
   };

});

"this" 仅适用于 showAlert1 和 showAlert2,因为您在此处将它们称为控制器本身的 属性:

<button class="button button-primary" ng-click="popup.testAlert()">

最好使用 $scope:

<html ng-app="mySuperApp">
  <head>
    <meta charset="utf-8">
    <title>
      Popups
    </title>

    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">

    <link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
    <script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>

  </head>
  <body class="padding" ng-controller="PopupCtrl">
    <button class="button button-primary" ng-click="testAlert()">
      Test Alert
    </button>
    <button class="button button-positive" ng-click="showAlert1()">
      Alert1
    </button>
    <button class="button button-positive" ng-click="showAlert2()">
      Alert2
    </button>

    <script id="popup-template.html" type="text/ng-template">
      <input ng-model="data.wifi" type="text" placeholder="Password">
    </script>
  </body>
</html>

然后是 JS:

angular.module('mySuperApp', ['ionic'])
.controller('PopupCtrl',function($scope, $ionicPopup) {

   $scope.testAlert = function() {
     alert('Alerting!');
   };

   $scope.showAlert1 = function() {
     $ionicPopup.alert({
       title: 'Don\'t eat that!',
       template: 'It might taste good'
     }).then(function() {
       $scope.testAlert();
     });
   };

   $scope.showAlert2 = function() {
     $ionicPopup.alert({
       title: 'Don\'t eat that!',
       template: 'It might taste good'
     }).then(function() {
       $scope.testAlert();
     });
   };
});