【问题标题】:Scope in TypeScript/angularJS HTTP GET requestTypeScript/angularJS HTTP GET 请求中的范围
【发布时间】:2013-08-17 16:17:48
【问题描述】:

我是 typescript 和 angular.js 的新手,我正在为 http get 请求而苦苦挣扎。 我使用 DefinitelyTyped 来定义 Angular 的类型。

我的控制器代码如下所示:

module game.Controller {
    'use strict';

    export interface IGameScope extends ng.IScope {
        vm: GameCtrl;
    }

    export class GameCtrl {

        private bonus: any;
        private http: any;

        constructor($scope: IGameScope, $http: ng.IHttpService, $location: ng.ILocationService) { 
            $scope.vm = this;
            this.http = $http;
        }

        doBet() {
            this.http.get('http://localhost:9000/db').success(function(data: any, status: any) { 
                    this.bonus = data;
                }
            );
        }
    }

}

我的看法是这样的:

<button ng-click="vm.doBet()">bet</button>
<div><span>bonus: {{ vm.bonus }}</span></div>

当我在没有 http 请求的情况下更改奖励变量时,视图模型绑定工作正常。但是当我尝试在 get 请求的成功函数中更新奖励变量时,出现以下错误:

TypeError: Cannot set property 'bonus' of undefined

如何实现更新成功函数中的变量?

如果有更好/更清洁的方法或做法来更新请求数据,我也将不胜感激

【问题讨论】:

    标签: angularjs typescript angularjs-scope


    【解决方案1】:

    这可以使用 TypeScript 的 lambda 表达式轻松完成:

    doBet() {
        this.http.get('http://localhost:9000/db').success(
            (data, status) => this.bonus = data
        );
    }
    

    【讨论】:

    • 你对这个话题有更多的解释吗?例如。 a 为什么我们必须在这里使用 lambda 表达式?
    • 在普通的 js 中你会拥有例如this.http.get('url').success(function(data, status) { ... });,所以this 在成功函数中不可见。如上所示的lamba表达式自动编译为var _this = this; this.http.get('url').success(function(data, status) { _this.member = "something"; });,因此this通过辅助变量_this在范围内可见。希望有帮助。
    【解决方案2】:

    我没有使用过打字稿,但对我来说它看起来像是一个闭包/范围问题。您的成功回调是异步运行的,因此 this 的值在内部是不同的。尝试使用this 绑定函数回调。

    this.http.get('http://localhost:9000/db').success(angular.bind(this,
        function(data: any, status: any) {this.bonus = data;});
    

    【讨论】:

    • 这在打字稿中不是必需的。请参阅 3x14159265 的答案。
    【解决方案3】:

    您可以将方法放在构造函数中,以便像这样访问 $scope:

    constructor($scope: IGameScope, $http: ng.IHttpService, $location: ng.ILocationService) {
        $scope.vm = this;
        this.http = $http;
    
        $scope.doBet = function() {
            this.http.get('http://localhost:9000/db').success(function (data: any, status: any) {
                $scope.bonus = data;
            });
        }
    }
    

    这是一个tutorial,关于使用 AngularJS 和 Typescript。

    【讨论】:

    • 谢谢,我已经阅读了本教程。但是在控制器中定义所有范围函数真的是最佳实践吗?此外,我将$scope.vm 变量绑定到我的控制器实例,以省略将每个范围变量绑定到我的控制器变量的需要。所以恕我直言,在这种情况下,使用绑定 $scope.vm = this; 不会有任何改进。
    • @3x14159265 我认为使用 TypeScript 真的是太杀了,它使 JavaScript 变得复杂。
    【解决方案4】:

    this.bonus = data;中的this其实是指success里面的回调函数。

    您可以这样做:$scope.vm.bonus = data;

    【讨论】:

    • 这不起作用,因为$scope 仅在构造函数中可见,而在doBet() 函数中不可见。
    • @3x14159265 将doBet() 移动到您的构造函数中并将其声明为$scope 上的方法:$scope.doBet = function() { ... };,或者直接将$scope 传递到doBet()
    • @3x14159265 在 2 个选项中,我最好将 doBet 移动到控制器内并在作用域上声明它。
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 2015-02-04
    • 2015-08-16
    • 2014-08-23
    • 1970-01-01
    相关资源
    最近更新 更多