【问题标题】:Losing this reference in $scope.$on event在 $scope.$on 事件中丢失此引用
【发布时间】:2015-06-25 15:25:27
【问题描述】:

我通过设置回调函数从 Angularjs 注册“$routeChangeSuccessEvent”。引发事件时,我无法通过“this”访问我的控制器实例。当前这个实例是未定义的。

我的完整 TypeScript 代码:

export class Ctlr {

    static $inject = ["$rootScope","$route"];

    constructor(private $scope: ng.IRootScopeService) {
        this.Scope = $scope;
        this.Title = "";
        //this.Scope.$on("$routeChangeSuccessEvent", this.onRouteChangeStart);
        this.RegisterEvents();
        }
    private RegisterEvents(): void {
        this.Scope.$on("$routeChangeSuccessEvent",(event: ng.IAngularEvent, args: any) => {
        //this is undefined
            console.log(this);
        });
    }
    public Scope: ng.IScope;
    public Title: string;

    public onRouteChangeStart(event: ng.IAngularEvent, args: any) {
        //this is undefined
        this.Title = args.$$route.name);
    }

}

}

我可以通过以下方式访问 Title 属性:

 private RegisterEvents(): void {
        var ref = this.Title;
        this.Scope.$on("$routeChangeSuccessEvent",(event: ng.IAngularEvent, args: any) => {
            ref = args.$$route.name;
        });
    }

但这不是一个真正的解决方案,因为 angularJS 不会更新它的视图。看来我没有找到正确的参考。如果那不可能,那么整个 angularjs 事件似乎都不是 useabel - 那不可能吗?

我也没有找到任何关于这种奇怪行为的话题。这个问题有解决办法吗?

【问题讨论】:

  • 小提示:constructor(private $scope: ...) 表示$scope 被放置在对象属性中,因此this.Scope = $scope; 是多余的。只需使用this.$scope

标签: javascript angularjs typescript


【解决方案1】:

触发回调时范围会发生变化,这就是this 变为未定义的原因。

你的另一个例子:

var ref = this.Title;

实际上只是创建了Title 的副本,因为它是原始类型(字符串)。这就是为什么它也不起作用。更新ref 不会更新this.Title

对此的通常解决方案是将定义开始为:

var vm = this;

...
private RegisterEvents(): void {
    this.Scope.$on("$routeChangeSuccessEvent",(event: ng.IAngularEvent, args: any) => {
    //this is undefined
        console.log(vm);
    });
}

因此,与其到处使用this,不如使用vm。请注意,vm 可以任意命名。重要的部分是您在this 是您要在回调中使用的范围内捕获对this 的引用。这是因为this不是原始类型,因为它是一个对象,而不是获取副本,而是获取引用。

您的另一个选择是使用bind,您可以将其应用于任何函数,该函数本质上告诉JavaScript this 将等同于什么。例如

$scope.$on("SomeEventHere", someCallbackFunction.bind(this));

这是您在此处使用的偏好问题,但通常我看到人们使用var something = this; 方法。

【讨论】:

  • 我正在使用 TypeScript v1.7,并且对于第一个代码 sn-p,我没有在其中得到 undefined :(
【解决方案2】:

这是因为 this 总是引用它的父级,也就是现在的函数。因此,如果您愿意,可以这样做:

private RegisterEvents(): void {
    var ref = this;
    this.Scope.$on("$routeChangeSuccessEvent",(event: ng.IAngularEvent, args: any) => {
        console.log(ref);
    });
}

【讨论】:

    【解决方案3】:

    你可以重新绑定这个变量: this.Scope.$on("$routeChangeSuccessEvent",this.onRouteChangeStart.bind(this));

    【讨论】:

      【解决方案4】:

      正如在其他解决方案中所述,并且至少使用 TypeScript v1.7,您可以使用如下粗箭头来使用它:

      $scope.$on('some-event', () => { console.log('here `this` is not undefined'); });
      $scope.$watch('foo.bar', (a,b) => { console.log('here too...'); }
      $scope.$on('$routeChangeSuccessEvent', () => { console.log('here too...'); });
      

      但是,如果您想传递对同一类中的函数的引用,则必须使用 .bind(this) 表示法:

      $cope.$on('$routeChangeSuccessEvent', this.onRouteChangeStart.bind(this));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-02-05
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多