Angular JS,工厂作为本地文件,文件中包含JSON

时间:2015-03-17 20:44:52

标签: javascript json angularjs

我正在尝试修改以下Angular JS示例,因此它可以作为未连接到Internet的设备上的文件夹中的独立文件。 http://curran.github.io/screencasts/introToAngular/exampleViewer/#/44

我可以在流程结束时本地链接两个库,我相信我已经正确引用了模板。我已经为JSON数据(countriesArray)创建了一个本地数组,但我不知道如何正确加载到国家/地区工厂,没有http。我暂时使用了该示例的JSON URL,但代码必须有另一个错误,因为它只显示一个空白屏幕。

对不起我的无知。

<html ng-app="countryApp">
      <head>
        <meta charset="utf-8">
        <title>Angular.js Example</title>
        <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.10/angular.min.js"></script>
        <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.10/angular-route.min.js"></script>
        <script>
          var countryApp = angular.module('countryApp', ['ngRoute']);
    	  var countriesArray = [
      {
        "name": "China",
        "population": 1359821000,
        "flagURL": "//upload.wikimedia.org/wikipedia/commons/f/fa/Flag_of_the_People%27s_Republic_of_China.svg",
        "capital": "Beijing",
        "gdp": 12261
      },
      {
        "name": "India",
        "population": 1205625000,
        "flagURL": "//upload.wikimedia.org/wikipedia/en/4/41/Flag_of_India.svg",
        "capital": "New Delhi",
        "gdp": 4716
      },
      {
        "name": "United States of America",
        "population": 312247000,
        "flagURL": "//upload.wikimedia.org/wikipedia/en/a/a4/Flag_of_the_United_States.svg",
        "capital": "Washington, D.C.",
        "gdp": 16244
      }
    ];
          countryApp.config(function($routeProvider) {
            $routeProvider.
              when('/', {
                template: '<ul><li ng-repeat="country in countries"><a href="#/{{country.name | encodeURI}}">{{country.name}}</a></li></ul>',
                controller: 'CountryListCtrl'
              }).
              when('/:countryName', {
                template: '<h1>{{country.name}}</h1><ul><li>Flag: <img ng-src="{{country.flagURL}}" width="100"></li><li>Population: {{country.population | number }}</li><li>Capital: {{country.capital}}</li><li>GDP: {{country.gdp | currency }}</li></ul>',
                controller: 'CountryDetailCtrl'
              }).
              otherwise({
                redirectTo: '/'
              });
          });
    
          countryApp.factory('countries', function(){
            function getData(callback){
              $http({
                method: 'GET',
                url: 'http://curran.github.io/screencasts/introToAngular/examples/snapshots/snapshot42/countries.json',
                cache: true
              }).success(callback);
            }
    
            return {
              list: getData,
              find: function(name, callback){
                getData(function(data) {
                  var country = data.filter(function(entry){
                    return entry.name === name;
                  })[0];
                  callback(country);
                });
              }
            };
          });
    
          countryApp.controller('CountryListCtrl', function ($scope, countries){
            countries.list(function(countries) {
              $scope.countries = countries;
            });
          });
    
          countryApp.controller('CountryDetailCtrl', function ($scope, $routeParams, countries){
            countries.find($routeParams.countryName, function(country) {
              $scope.country = country;
            });
          });
    
          countryApp.filter('encodeURI', function(){
            return window.encodeURI;
          });
        </script>
      </head>
      <body>
        <div ng-view>{{countries}}</div>
      </body>
    </html>

1 个答案:

答案 0 :(得分:2)

首先,您的国家/地区最好放在工厂而不是全局变量。

然后,在工厂的函数getData中,不是让http调用只是将数组传递给你的回调。

工厂看起来如下:

countryApp.factory('countries', function () {

    var countriesArray = [ ... ];

    function getData(callback) {
        return callback(countriesArray);
    }

    return {
        list: getData
    };
});

请参阅fiddle


避免使用回调:

您以前的getData函数用于将结果传递给回调,而来自控制器的调用如下:

countries.list(function (countries) {
    $scope.countries = countries;
});

但你可以尝试避免使用回调并使用 thenable 代替:

1)注入$q作为工厂的依赖

2)将getData重写为:

function getData() {
    return $q.when(countriesArray);
}

如果您不习惯,请注意return $q.when(countriesArray)可能看起来有点棘手。但这并不是很困难。在这里,我们确实说&#34;当countriesArray被解析时返回&#34; 。由于countries数组不是异步的,我们可以立即返回,$q.when将对象包装到$ q保证中,因此调用者可以按如下方式调用getDatagetData.then(...)

3)现在,来自控制器的调用如下:

countries.list().then(function (countries) {
    $scope.countries = countries;
});

请参阅second fiddle


从本地json

获取数据

如果您想从独立文件加载数据而不是将它们放在工厂中(这将是一个有价值的选择),您将不得不返回$http。您可以拨打本地网址,因此在未连接到互联网的设备上运行该网址绝对没有问题:

 function getData() {
    return $http.get('countries.json');
}

$http会返回一个承诺,因此对getData的调用保持不变:getData.then(...)

相关问题