【问题标题】:Angular callback or promise to trap return vale角度回调或承诺捕获返回值
【发布时间】:2016-06-09 21:25:10
【问题描述】:

我绞尽脑汁想让它正常工作。我已经尝试过回调和承诺,并且对两者都持开放态度。我使用 Joe Eames 在 Pluralsight 类中提出的 Mean Stack 对我的代码进行建模。我还在学习,所以如果我的术语不正确,请原谅我的术语,但这是它如何与代码一起使用,如下所示。

我的界面调用 flQuestionCrudCtrl.createQuestion 调用 flQuestionCrud.createNewQuestion 调用 flQuestion.Create。 flQuestion.Create 向写入 mongodb 集合的服务器发出 http post 请求。一切似乎工作正常,数据被写入数据库,我可以在每个控制台日志中看到 flQuestionCrud 中的返回值。当我尝试读取 flQuestionCrudCtrl 中的“数据”返回参数时,我得到“错误:数据未定义”。我已经尝试了回调和承诺的每一种组合,但无法让它发挥作用。你能看出我做错了什么吗?

  angular.module('app').controller( 'flQuestionCrudCtrl',function(flConstructDataService, flQuestionDataService, flQuestionCrud, flCachedReferenceData,flCachedQuestions, flAnswer, $scope, $location, $q, flIdentity, flNotifier,$timeout, $state) {


$scope.createQuestion = function() {

function doWorkAsync() {
    return $timeout(flQuestionCrud.createNewQuestion(currentQuestionData), 10);
}

doWorkAsync()
    .then(function(data) {
        console.log("flQuestionCrudCtrl - Success " + data);
        console.log("flQuestionCrudCtrl - Success Statement " + data.statement);
        console.log("flQuestionCrudCtrl - Success Question id " + data._id);
        currentQuestionData._id = data._id;
        flQuestionDataService.setNewQuestionId(data._id);
        console.log("flQuestionCrudCtrl - currentQuestionData._id " + currentQuestionData._id);
        console.log("flQuestionCrudCtrl - flQuestionDataService.getNewQuestionId() " + flQuestionDataService.getNewQuestionId());
        $state.go('questionUpdate');
    })
    .catch(function(err) {
        console.log("flQuestionCrudCtrl - Error " + err);
        $state.go('questionCreate');
    })
    .finally();
};

}


angular.module('app').factory('flQuestionCrud',function($http, $q, $state, $timeout, flQuestion ){
    return {
        createNewQuestion: function(newQuestionData) {
            console.log("Before - flQuestion.create");

        function createQuestionDataAsync(questionData) {
            console.log("flQuestionCrud - Before Call to create ")
            var returnData;
            flQuestion.create(questionData, function(data) {
                console.log("flQuestionCrud - After Call to create ")
                if (!data){
                    return Error("Error Creating Data");
                    //return null;
                }
                else {
                    console.log("flQuestionCrud - Try Section - Success " + data);
                    console.log("flQuestionCrud - Try Section - Success Statement " + data.statement);
                    console.log("flQuestionCrud - Try Section - Success Question id " + data._id);
                }
                return data;
            });
        }

        createQuestionDataAsync(newQuestionData); 
    },

【问题讨论】:

  • 当您尝试将数据记录到 doWorkAsync 函数的“then”部分时,是否收到“未定义”错误?
  • 是的,第 198 行是我尝试显示该语句的第二条日志语句。第一个日志语句显示未定义。下面是第一个日志语句的输出,然后是错误。之前 - flQuestion.create flQuestionCrud.js:4:13 flQuestionCrud - 在调用之前创建 flQuestionCrud.js:46:17 flQuestionCrudCtrl - 成功未定义 flQuestionCrudCtrl.js:197:17 错误:数据未定义 $scope.createQuestion/localhost:3030/vendor/angular/angular.js:14792:28

标签: angularjs callback angular-promise


【解决方案1】:

您的flQuestionCrud.createNewQuestion() 方法应该返回用data 解决的承诺:

angular.module('app')
    .factory('flQuestionCrud', function($http, $q, $state, $timeout, flQuestion ){
        return {
            createNewQuestion: function(newQuestionData) {
                var deferred = $q.defer();

                flQuestion.create(questionData, function(data) {
                    if (data){
                        // whatever we resolve the promise with will be passed 
                        // to the `then` handler in the controller
                        deferred.resolve(data);
                    }
                    else {
                        deferred.reject("Error Creating Data");
                    }
                });

                return deferred.promise;
            }
            // ...
        }
    });

请注意,我们明确地创建了承诺并根据flQuestion.create() 返回的内容来解决或拒绝它。

这样您就可以按照自己的方式访问控制器中的data

flQuestionCrud.createNewQuestion(currentQuestionData)
    .then(function(data) {
        // work with data here
    });

doWorkAsync()
    .then(function(data) {
        // work with data here
    });

【讨论】:

  • 谢谢,谢谢,谢谢。尴尬地说我花了多长时间试图让它发挥作用。在所有的阅读和示例中,promise 看起来像魔术,而您的解决方案表明它是我只需要接受的幕后魔术。顺便说一句,我在控制器中的东西不起作用,不知道为什么,但你建议的东西很好。非常感谢您对此提供帮助。我会更频繁地与我们联系。
  • @j-terranova,不客气。如果答案解决了您的问题,您应该将其标记为“已接受”。