在启动时从角度服务加载数据

时间:2015-05-19 09:30:02

标签: angularjs

更新

我目前正在这样做,我不知道为什么会这样,但我不认为这是正确的方法。我可能会滥用消化周期,无论那些是什么。

首先,我希望将数组navigationList放在服务中,以便将其传递到任何地方。该服务还将更新该阵列。

app.factory('ChapterService', [ 'ExtService', function(ExtService) {

  var navigationList = [];

  var getNavigation = function() {
    ExtService.getUrl('navigation.json').then(function(data) {
      angular.copy(data.navigationList, navigationList);
    });
  }
  return{
   getNavigation: getNavigation,
    navigationList: navigationList,
}
}]);

然后在我的控制器中,我调用服务来更新数组,然后我将范围变量指向它。

  ChapterService.getNavigation();
  $scope.navigationList = ChapterService.navigationList;
  console.log($scope.navigationList);

但这是奇怪的地方。 console.log返回一个空数组[],但我的html中有一个使用$scope.navigationList的ng-repeat,并且它正确地显示了该数组中的项目...我认为这有与消化周期有关,但我不确定。任何人都可以向我解释并告诉我,我是否以错误的方式接近这个?

我有一个运行功能和计算的主工厂。我正在尝试运行

app.factory('ChapterService', [ 'ExtService', function(ExtService) {

  var navigation = {
    getNavigationData : function () {
      ExtService.getUrl('navigation.json').then(function(data) {
        return data;
      });
    }
  }

  return: {
       navigation: navigation

}

我在console.log之前点了data才返回它并且它是正确的数据,但由于某种原因,我无法将其返回.. 具有getUrl方法的ExtService就是通常使用的方法(它返回一个promise) 在我的控制器中,我想做类似

的事情
$scope.navigation = ChapterService.navigation.getNavigationData();

为了在应用初始化时从文件加载数据, 但是当我运行

时,这不起作用
console.log(ChapterService.navigation.getNavigationData());

我得到null,但我不知道为什么。我应该使用app.run()这样的事情吗?我需要在完成任何其他操作之前加载这些数据,我不认为我使用了最佳方法...

修改

我不确定我是否应该做类似于jsfiddle中所做的事情,这种模式对我来说是不熟悉的,所以我不确定如何重新制作以满足我的需求为目的

我的ExtService代码是

app.factory('ExtService', function($http, $q, $compile) {
   return {
     getUrl: function(url) {
       var newurl = url + "?nocache=" + (new Date()).getTime();
       var deferred = $q.defer();
       $http.get(newurl, {cache: false})
        .success(function (data) {
            deferred.resolve(data);
        })
        .error(function (error) {
            deferred.reject(error);
        });

      return deferred.promise;
     }
   }
});

编辑2

我希望将请求逻辑与控制器分开,但同时在应用启动时完成。我希望服务功能只返回数据,所以我不需要做进一步的事情。然后或者成功...

3 个答案:

答案 0 :(得分:1)

您正在使用Promise。想想这意味着什么:

var navigation = {
    getNavigationData : function () {
        ExtService.getUrl('navigation.json').then(function(data) {
            return data;
        });
    }
}

getNavigationData是一个不返回任何内容的函数。当你在“then”子句中时,你处于不同的函数中,因此return data仅从内部函数返回。事实上,.then(function(data) { return data; })是无操作。

理解承诺的重要一点是,一旦你处于承诺范式,就很难摆脱它 - 你最好的选择就是留在里面。

首先,从你的函数中返回一个承诺:

app.factory('ChapterService', [ 'ExtService', function(ExtService) {
    var navigation = {
        getNavigationData: function () {
            return ExtService.getUrl('navigation.json');
        }
    }

    return {
        navigation: navigation
    }
}])

然后在您的控制器中使用该承诺:

app.controller('MyController', function($scope, ExtService) {
    ExtService
        .navigation
        .getNavigationData()
        .then(function(data) {
            $scope.navigation = data;
        });
})

更新

如果您真的想要避免承诺范例,请尝试以下方法,但我建议在此之前彻底了解此方法的含义。您从服务返回的对象不会立即填充,但一旦调用返回,Angular将完成摘要周期,并且将刷新任何范围绑定。

app.factory('ChapterService', [ 'ExtService', function(ExtService) {
    var navigation = {
        getNavigationData: function () {
            // create an object to return from the function
            var returnData = { }; 

            // set the properties of the object when the call has returned
            ExtService.getUrl('navigation.json')
                .then(function(x) { returnData.nav = x });

            // return the object - NB at this point in the function,
            // the .nav property has not been set
            return returnData;
        }
    }

    return {
        navigation: navigation
    }
}])

app.controller('MyController', function($scope, ExtService) {
    // assign $scope.navigation to the object returned
    // from the function - NB at this point the .nav property
    // has not been set, your bindings will need to refer to
    // $scope.navigation.nav
    $scope.navigation = ExtService
        .navigation
        .getNavigationData();
})

答案 1 :(得分:0)

您正在使用承诺,因此请返回该承诺并使用控制器中的解析(.then):

app.factory('ChapterService', [ 'ExtService', function(ExtService) {

    var navigation = {
        getNavigationData: function () {
            return ExtService.getUrl('navigation.json'); // returns a promise
        });
    }

    return: {
        navigation: navigation
    }
}

控制器:

ChapterService
    .navigation
    .getNavigationData()
    .then(function (data) {
        // success
        $scope.navigation = data;
    }, function (response) {
        // fail
    });

答案 2 :(得分:0)

这是一种不同的方法,我不知道你的数据是什么样的,所以我无法为你测试它。

<强>控制器

.controller('homeCtrl', function($scope, $routeParams, ChapterService) {
    ChapterService.getNavigationData();
})

<强>工厂

.factory('ChapterService', [ 'ExtService', function(ExtService)  {

        function makeRequest(response) {
            return ExtService.getUrl('navigation.json')
        }

        function parseResponse(response) {
            retries = 0;
            if (!response) {
                return false;
            }
            return response.data;
        }

        var navigation =  {
            getNavigationData: function () {
                return makeRequest() 
                    .then(parseResponse)
                    .catch(function(err){
                        console.log(err);
                    });
            }
        }

        return navigation;


    }])