繁体   English   中英

使用匿名函数和$ q promises时AngularJS'this'问题

[英]AngularJS 'this' issue when using anonymous functions and $q promises

因此我们都知道'this'在JavaScript中是一个棘手的关键字,并且匿名函数和AngularJS承诺使其变得更加棘手。

问题(TL&DR版本)

允许promise回调使用与发起请求的服务相同的“ this”的正确(角度)方法是什么?

有关示例,请参见此小提琴:

http://jsfiddle.net/tpeiffer/CFD3e/

控制器上的所有这些方法都会调用Tier1Service。 然后,Tier1Service取消调用WorkerService以获取数据。 加载数据后,它将通过承诺将所述数据返回给Tier1Service。 返回的数据被设置为Tier1Service_data属性。

Alternate 3很干净并且可以工作,但是感觉必须有更好的方法。

备用4也很干净并且可以使用,但是看起来还是错误的。

现在,我真正想要的是$ q承诺为我做所有这些事情。 :)

以下是相关代码:

// App.js
    angular.constructor.prototype.call = function (scope, func) {
        return function () {
            func.apply(scope, arguments);
        };
    };

// Tier1Service
        get coolData() {
            return this._data;
        },
        set coolData(val) {
            this._data = val;
        },
        doWorkAlt1: function () {
            mySubWorkerService.someData.then(function (data) {
                // FAILS because 'this' is the window, 
                // not the service
                if (data) this._data = data;
            });
        },
        doWorkAlt2: function () {
            mySubWorkerService.someData.then((function (data) {
                // FAILS because data is undefined because
                // the function is wrapped in an anonymous
                // function
                if (data) this._data = data;
            }).call(this));
        },
        doWorkAlt3: function () {
            // WORKS because I keep track of the instance
            var instance = this;
            mySubWorkerService.someData.then(function (data) {
                if (data) instance._data = data;
            });
        },
        doWorkAlt4: function () {
            // WORKS because I keep pass 'this' around
            mySubWorkerService.someData.then(angular.call(this, function (data) {
                if (data) this._data = data;
            }));
        }

// WorkerService
        get someData() {
            var deferred = $q.defer();
            deferred.resolve('i got back data!!');
            return deferred.promise;
        }

您应该能够使用Function.bind达到所需的结果:

doWork: function () {        
    mySubWorkerService.someData.then((function(data) {
        //this now refers to whatever it referred to in the doWork function
    }).bind(this));
}

请注意,但是bind在较旧的浏览器中不可用。 但是,如果需要,可以很容易地手动将其修补到原型中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM