AngularJs $q.defer()不起作用

5

我在使用 $q.defer(); 时遇到了一些问题。
当我使用回调函数代替后,我的代码可以工作(视图被更新),但是使用$q.defer();无法工作

这是我的代码:
这个服务:

eventsApp.factory('eventData', function($http, $q) {
    return {
        getEvent: function(callback) {
            var deferred = $q.defer();
            $http({method: 'GET', url: '/node/nodejsserver/server.js'}).
                success(function(data, status, headers, config){
                    //callback(data.event);
                    deferred.resolve(data.event);
                    console.log('status: ', status, ' data: ', data);
                }).
                error(function(data, status, headers, config){
                    deferred.reject(status);
                    console.log('status: ', status);
                });
            return deferred.promise;
        }
    };
});

控制器:
eventsApp.controller('EventController', 
    function EventController($scope, eventData) {
        $scope.event = eventData.getEvent();
    }
);

但它没有起作用。

后来我发现了这个答案,然后我像这样更新了我的控制器:

eventsApp.controller('EventController', 
    function EventController($scope, eventData) {
        eventData.getEvent().then(function(result) {
           $scope.event = result;
        });
    }
);

它可以工作。
非工作代码和工作代码的区别是什么?

2个回答

11

这段代码使用了自动承诺解包,但自动解包在最近版本的Angular中已经被弃用和删除。它被认为是过于神奇。

以前,当您返回一个Promise时,Angular会执行以下操作:

  • 返回空数组。
  • 稍后在请求到达时填充它。
  • 自己触发数据变更检测。

Angular开发人员认为这种行为令人困惑并且神奇,因此在Angular 1.2中将其弃用,在不久的将来(1.3)将其移除。通过承诺分配值的正确方法如第二个示例所示:

eventData.getEvent().then(function(result) {
    $scope.event = result;
});

来自 Angular 1.3(未确定)发布文档:

$parse:由于fa6e411d,已删除 promise unwrapping 这一功能。自从 1.2.0-rc.3 版本以来,它已被弃用。无法再打开此功能。已删除了两种方法:

同时从 1.2 版本的文档中:

$parse 和模板一般不再自动取消 promise 的包装。

之前:

$scope.foo = $http({method: 'GET', url: '/someUrl'}); <p>{{foo}}</p>

之后:

$http({method: 'GET', url: '/someUrl'})

.success(function(data) { $scope.foo = data; });``

{{foo}}

`

该功能已被弃用。如果绝对需要,现在可以通过 $parseProvider.unwrapPromises(true) API 重新启用它。

顺便避免延迟反模式$http 已经返回了 promise,所以你可以简单地 return 它而不是使用 $q.defer


谢谢Benjamin,你的回答非常有帮助。 - trajce

1

编辑:查看Benjamin的答案。

在您的服务中,您返回一个promise对象,promise对象具有.then方法。

您将promise对象分配给$scope.event,因此您将无法获得数据(根据Benjamin的最新版本)

当您使用deferred.resolve(data.event)解决承诺时,传递给.then方法的函数将以这个已解决的数据调用。

您可以给.then提供第二个参数,当您执行deferred.reject()时会调用该参数。

这是承诺API的基本功能。只需阅读文档以获取更多信息https://docs.angularjs.org/api/ng/service/$q


1
这实际上曾经是可行的,直到最近你可以将一个Promise对象分配给作用域属性 - 有关更多信息,请参见我的答案。 - Benjamin Gruenbaum
好的,谢谢你提供的信息:),我不知道那个,当它停止工作时,我以为是错误的方法:) - Vamsi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接