【问题标题】:Why can't I assign to a class variable from a $http success handler? [duplicate]为什么我不能从 $http 成功处理程序分配给类变量? [复制]
【发布时间】:2018-05-27 21:44:09
【问题描述】:

对于我正在进行的一个项目,我发现了一个没有多大意义的情况。我强烈怀疑,当我使用 TypeScript 时,我的特殊问题是由于 javascript 的一个有趣的细微差别造成的,但我不知道如何证明或修复它。 p>

背景
对于我正在处理的应用程序,我有一个相当基本的服务,它负责与 Web API 通信。

与我通常所做的唯一不同的是,我没有使用 TypeScript 的 'lambda' 语法来处理 $http.get(...).then(...) 成功回调,而是使用类函数,因为 A) 我使用的代码是实际使用错误回调,并且 B) $http.get(...).then(success, error) 语法使用 lambda 语法阅读起来有点混乱。

// Not pretty, but sufficient.
this.$http.get(...).then(() => { ... });

// Ewwww...
this.$http.get(...)
    .then(() => {
        ...
    }, () => {
        ...
    });

// Much better!
this.$http.get(...)
    .then(onFooSuccess, onError);

以下是相关服务:

namespace MyApp.Models {
    export class WebApiResult<T> {
        public data: T;
    }
}

namespace MyApp.Services {
    export class SomeService {
        public status: SomeServiceStatus = new SomeServiceStatus();

        public static $inject: string[] = ['$http'];
        public constructor(
            public $http: ng.IHttpService
        ) {
        }

        public doSomething(): ng.IPromise<SomeServiceStatus> {
            this.$http.get('/api/some/SomeAction')
                .then(this.onDoSomethingSuccess, this.describeError);
        }

        // This is the problem method.  When this code runs,
        // a type error is generated.
        public onDoSomethingSuccess(result: Models.WebApiResult<SomeServiceStatus>): SomeServiceStatus | ng.IPromise<SomeServiceStatus> {
            if(!result.data.isInSpecialState) {
                return result.data;
            }

            // TypeError!  Can't assign to undefined.
            this.status = result.data;

            return result.data;
        }

        public describeError(error: any) {
             alert('oops');
        }
    }

    export class SomeServiceStatus {
        public isInSpecialState: boolean = false;
        public someStatusMessage: string = '';
        public someIdentifier: string = '';
    }

    angular
        .module('app')
        .service('someService', SomeService);
}

问题
因此,无论何时调用此服务,都会成功执行 $http 获取。问题在于成功回调,但是 - 当this.status = result.data 行被命中时,由于无法将result.data 分配给undefined 的属性status,它总是抛出异常。

目前,我的理论是this 实际上并不引用SomeService,而是其他的东西,甚至可能是用作委托的类方法。

问题
这个理论引出了一些问题。

  1. this 到底指的是什么?在 Visual Studio 2015 中将鼠标悬停在它上面会显示“有用”文本:this: this。感谢微软。
  2. this 应该这样做吗?这是 TypeScript 的错误,还是只是我用生成的 JavaScript 打自己的脚?
  3. 在处理既有成功回调又有错误回调的 AngularJS 承诺时,是否有任何推荐的风格选择?可能是我没有看到更好的编写代码的方法,或者我根本不知道什么。这不是第一次提出 SO 问题教会了我一些东西。

【问题讨论】:

  • 您是否查看过带有thistypescript/javascript 标记的任何其他问题?
  • 我在写这个问题之前做了搜索,但我没有找到任何解决这个问题的东西。另外,除非你是一个非常快速的阅读者,否则我不确定你是否阅读了我的问题。
  • 您无需阅读整个问题即可了解问题所在。这很明显。
  • 尝试改变它:` public doSomething(): ng.IPromise { this.$http.get('/api/some/SomeAction') .then(onDoSomethingSuccess, describeError) ; } ` to: ` public doSomething(): ng.IPromise { this.$http.get('/api/some/SomeAction') .then((result) => this.onDoSomethingSuccess(result), describeError) ; } `
  • 您将函数传递给 .then()。然后,该函数将在与允许它访问您希望它访问的this 的上下文不同的上下文中执行。您可以通过传递一个匿名函数而不是调用该方法来解决它,或者您可以绑定它。

标签: angularjs typescript callback typeerror handle


【解决方案1】:

这是一个 JavaScript 的东西。 如果你提供一个函数实例,或者像这样用经典的 JavaScript 编写:

..then(function(data) { ...}, function(error) { ... })

然后,与新的 lambda 表达式不同,JavaScript 以旧方式运行,“this”被设置为指向这些处理程序的 doSomething() {} 内的范围。

但是 bind() 可以帮助你保持你漂亮的语法完整,稍微冗余:

public doSomething() {
    this.$http.get('/api/some/SomeAction')
        .then(this.onDoSomethingSuccess.bind(this), this.describeError.bind(this));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    相关资源
    最近更新 更多