【问题标题】:Why is 'this' losing context in new Angular 1.5 components?为什么“this”在新的 Angular 1.5 组件中会丢失上下文?
【发布时间】:2023-03-17 12:55:01
【问题描述】:

在使用新组件时遇到了一个非常奇怪的问题。当我们有一个 1.4 指令时,我们有以下代码......

(function () {
  'use strict';

angular.module('app.board').directive('dcCb', dcClipboardCopy);

  function dcCb() {
    return {
      link : function(scope, elem) {

        var clipboard = new Clipboard(elem[0]);

        elem.on('$destroy', function() {
          clipboard.destroy();
        });
      }
    };
  }
})();

clipboard.destroy() 函数内部如下...

Clipboard.prototype.destroy = function(){
    this.listeners.destroy();
}

在 1.4 中this 与元素相同,所以...

<button class="btn btn-sm btn-menu-outline copy-button" ...

所以这很好用,因为按钮元素似乎具有可以调用的 listeners 属性。

但是在升级到 1.5 之后,现在我们有了这样的组件....

(function() {
  'use strict';
  angular.module('app.board').component('dcCb', {
...
    controller: [ '$element','$scope',function($element,$scope) {

      var self = this;
      self.$postLink = postLink;
      function postLink(){
        var clipboard = new Clipboard($element[0]);
...
        $element.on('$destroy', clipboard.destroy);
      }

    }]
  });
})();

this(在剪贴板的销毁函数中)现在是控制器对象。所以尝试调用this.listeners 会引发错误。

第一个问题: 我知道新组件中的this 是组件范围,但在 1.4 中它是按钮元素。当然在这两个按钮元素中都应该是$element?我们在 1.4 中做错了吗?

第二个问题var clipboard = new Clipboard($element[0]) 不应该强制剪贴板中this 的上下文始终是剪贴板本身(由于new 关键字)?

【问题讨论】:

  • 有点困惑;您实际上是在使用 .component('name', {}) 语法并将链接函数中的内容移动到组件控制器吗?或者当您说“1.5 中的组件”时,您指的是其他东西?
  • 代码已更新.....是的,我们现在使用的是 .component 函数而不是指令函数。
  • 你在升级后的版本中使用了非常不同的功能......当然你失去了this。在 1.4 中,您使用匿名函数避免了这种情况。
  • 仅仅因为您创建了一个类的实例并不意味着当您将作为该实例一部分的函数传递给其他地方时它会保持上下文。任何东西都可以使用 .call 或 .apply 重新绑定它。事件处理程序总是这样做。

标签: javascript angularjs this


【解决方案1】:

您正在将一个在类上任意定义的函数交给窗口和事件侦听器,以便在与剪贴板实例不同的上下文中执行:

$element.on('$destroy', clipboard.destroy);

这是 javascript 中执行上下文的基本概念,我建议您阅读它。但是您可以通过简单地绑定您正在传递的函数的上下文来轻松解决您当前的问题:

$element.on('$destroy', clipboard.destroy.bind(clipboard));

【讨论】:

  • 但这并不能解释为什么 this 在 1.4 样式指令中的上下文是元素而在 1.5 中它是控制器(因此引发异常)的确切原因。感谢您的回复,这就是我已经尝试过的(并且有效)但是why这改变了吗?
  • 在 1.4 示例中,您将匿名函数传递给“on”事件侦听器。该函数对包含剪贴板实例的父范围有一个闭包。当稍后执行 anon 函数时,剪贴板的实例调用方法destroy。都好。在您的 1.5 示例中,您只是传递了 clipboard.destroy。那只是一个功能。它对上下文一无所知,然后以后调用该函数将是上下文。它改变的原因仅仅是因为你改变了代码。我会阅读上下文和闭包以了解更多信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 2016-05-03
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 2018-06-02
  • 1970-01-01
相关资源
最近更新 更多