如何在angularjs中将数据从工厂传递给我的控制器?

时间:2016-01-30 20:12:56

标签: javascript angularjs angularjs-service angularjs-controller angularjs-factory

我正在尝试将所有业务逻辑从我的控制器移到工厂,但是我在传递字段数据时遇到了一些问题。

factory.js

app.factory("Quote", function ($resource) {
    // TODO: this shouldn't start with /en/
    var quoteStatus = [];
    var quoteLanguage = [];

    var Quote = $resource("/en/quote/api/quote/:id", {}, {
        retrieve: {
          method: 'GET',
          params: {},
          isArray: true
        },
        query: {
          method: 'GET',
          params: {},
          isArray: true,
          url: '/en/quote/api/quote/'           
        },
        fields: {
          method: 'GET',
          url: '/en/quote/api/quote/fields/ '
        },
        update: {
          method: 'PATCH',
        },
    });

    Quote.fields().$promise.then(function (fields) {
        var tempObj = [];
        for (key in fields.status) {
            // must create a temp object to set the key using a variable
            tempObj[key] = fields.status[key];
            quoteStatus.push({
                value: key,
                text: tempObj[key]
            });
        }

        for (key in fields.language) {
            // must create a temp object to set the key using a variable
            tempObj[key] = fields.language[key];
            quoteLanguage.push({
                value: key,
                text: tempObj[key]
            });
        }

        //$scope.addLanguage($scope.language);

        Quote.status = quoteStatus;
        Quote.language = quoteLanguage;
    });

    return Quote;


});

controller.js

$scope.quoteStatus = Quote.status;

然而,由于 $ scope.quoteStatus 未定义,因此无效。我错过了什么?

提前致谢。

1 个答案:

答案 0 :(得分:2)

您不能期望异步操作以同步方式运行。

当控制器在其工厂函数中注入Quote时,创建时间Quote服务对象&然后调用Quote.fields()。如果您在控制器内询问Quote.status将始终返回undefined。你没有在任何地方保持承诺,以便控制器知道数据是否准备就绪。

我认为你应该在那里引入$q.when标志来检查Quote.fields()操作是否已完成&然后在那里得到所需的变量。

为了实现上述内容,您需要将Quote.fields()的承诺存储在服务中的某个地方。如下所示

var quoteFieldsPromise = Quote.fields().$promise.then(function (fields) {

   /// the code will be same here

};

然后添加新方法,该方法将保存quoteFieldsPromise promise对象并返回quoteStatus&的值。 quoteLanguage

var getQuoteDetails = function(){
   $q.when(quoteFieldsPromise).then(function(){
      return { quoteStatus: Quote.quoteStatus, quoteLanguage: Quote.quoteLanguage };
   })
}

但是你返回整个Quote对象的方式,只有$resource对象需要更改。我的意思是说我创建的getQuoteDetails方法不能与Quote对象一起返回。所以我宁愿重构服务到下面。

<强>服务

app.factory("Quote", function($resource, $q) {
    // TODO: this shouldn't start with /en/
    var quoteStatus = [], //kept private if needed
        quoteFieldsPromise, 
        quoteLanguage = [];//kept private if needed

    var QuoteApi = $resource("/en/quote/api/quote/:id", {}, {
        //inner code is as is 
    });

    //preserve promise of .fields() call
    quoteFieldsPromise = Quote.fields().$promise.then(function(fields) {
        //inner code is as is 
        //below lines are only changed.

        Quote.status = quoteStatus;
        Quote.language = quoteLanguage;
    });

    var getQuoteDetails = function() {
        return $q.when(quoteFieldsPromise).then(function() {
            return {
                quoteStatus: quoteStatus,
                quoteLanguage: quoteLanguage
            };
        })
    };

    return {
        QuoteApi: QuoteApi,
        getQuoteDetails: getQuoteDetails
    };
});

<强>控制器

Quote.getQuoteDetails().then(function(quoteDetails){
    $scope.quoteStatus = quoteDetails.quoteStatus;
    $scope.quoteStatus = quoteDetails.quoteLanguage;
});