$ q defer和promises以及如何在呈现视图之前使用它们来加载控制器的数据

时间:2012-09-06 20:00:22

标签: coffeescript angularjs promise

这是我发现的最相关的事情:https://stackoverflow.com/a/11972028/110233

当我只想回归一件事情似乎工作正常,但我不确定如何在其他事情依赖于第一件事情时返回多件事。

由于这有点迟钝,这里有一个我正在做的事情的小例子:

window.EventRosterCtrl = ($scope, subevent) ->
    $scope.subevent = subevent

EventRosterCtrl.resolve = 
    subevent: (SubEvent, $route) ->
        deferred = $q.defer()

        SubEvent.get {subevent_id: $route.current.pathParams.subevent_id}, (subevent) ->
            deferred.resolve subevent

        return deferred.promise

以下是我想要做的一个例子:

window.EventRosterCtrl = ($scope, subevent, addresses) ->
    $scope.subevent = subevent
    $scope.addresses = addresses

EventRosterCtrl.resolve = 
    subevent: (SubEvent, $route) ->
        deferred = $q.defer()

        SubEvent.get {subevent_id: $route.current.pathParams.subevent_id}, (subevent) ->
            deferred.resolve subevent

        return deferred.promise

    addresses: (User) ->
        deferred = $q.defer()

        # how do you get subevent called first and how would you access it here?
        for participant in subevent.participants
            User.get {user_id: participant.user}, (user) ->
                addresses[participant._id] = user.address

        deferred.resolve addresses

        return deferred.promise

3 个答案:

答案 0 :(得分:4)

你需要使用.then()

链接承诺
  var promise = firstOperation();
  promise = promise.then(function(value) {
    // do some more work
    return value; // it can be another promise
  });
  return promise; // this one will be resolved when both steps are resolved

答案 1 :(得分:2)

好的,所以你不能用那种方式来控制它,但想到一个解决方法(当一个分辨率依赖于另一个完成时),只需将所有内容放在一个对象中并解决它。结果最适合我的是提供服务,但要遵循我原来的例子:

window.EventRosterCtrl = ($scope, info) ->
    $scope.subevent = info.subevent
    $scope.addresses = info.addresses

EventRosterCtrl.resolve = 
    info: (SubEvent, User, $route, $q) ->
        deferred = $q.defer()
        resolvedInfo = {}

        SubEvent.get {subevent_id: $route.current.pathParams.subevent_id}, (subevent) ->
            resolvedInfo.subevent = subevent

            for participant in subevent.participants
                User.get {user_id: participant.user}, (user) ->
                    addresses[participant._id] = user.address

                    if addresses.length is subevent.participants.length
                        resolvedInfo.addresses = addresses
                        deferred.resolve resolvedInfo

        return deferred.promise

答案 2 :(得分:-1)

EventRosterCtrl仅在子事件准备好时初始化,因此以下内容应该有效:

window.EventRosterCtrl = ($scope, subevent) ->
    $scope.subevent = subevent

    for participant in subevent.participants
        User.get {user_id: participant.user}, (user) ->
            $scope.addresses[participant._id] = user.address

EventRosterCtrl.resolve = 
    subevent: (SubEvent, $route) ->
        deferred = $q.defer()

        SubEvent.get {subevent_id: $route.current.pathParams.subevent_id}, (subevent) ->
            deferred.resolve subevent

        return deferred.promise