关于在工厂内获取json数据的角度指导

时间:2014-11-23 20:28:12

标签: javascript json angularjs

我刚刚开始使用angular,我正在构建一个简单的项目管理应用程序,它从json文件加载项目,并在列表视图中显示项目。我将允许用户编辑和创建新数据,但我似乎无法通过第一步。

当我直接在列表控制器中加载数据时,它工作得很好。在阅读最佳实践的同时,您似乎不应该直接与控制器中的json文件通信,而是在工厂内处理这些事情(如果我弄错了,请告诉我)。我不能让它工作。这是我的代码:

var app = angular.module('itemsApp', ['ngRoute']);

app.config(function($routeProvider) {
  $routeProvider
    .when('/', {
      controller:'ListCtrl',
      templateUrl:'list.html'
    })
    .when('/edit/:itemId', {
      controller:'EditCtrl',
      templateUrl:'detail.html'
    })
    .when('/new', {
      controller:'CreateCtrl',
      templateUrl:'detail.html'
    })
    .otherwise({
      redirectTo:'/'
    });
})

app.factory('ItemsFactory',function($http){
  return {
    getItems: function() {
      return $http.get('js/items.json')
      .then(function(res){
        return res.data;
      });
    }
  };
});

app.controller('ListCtrl', function($scope, $http, ItemsFactory) {
  $http.get('js/items.json')
    .then(function(res){
      $scope.items = res.data;
  });
});

控制器工作得很好,但是,当我尝试将$ scope.items设置为ItemsFactory.getItems();的结果时,我什么也得不到。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

then promise方法内返回不会向getItems的调用者返回任何内容(与任何其他回调一样)。我建议你以这种方式管理这种情况:

app.factory('ItemsFactory',function($http){
  return {
    getItems: function() {
      return $http.get('js/items.json');
    }
  };
});

app.controller('ListCtrl', function($scope, ItemsFactory) {
  ItemsFactory.getItems().then(function(res){
    $scope.items = res.data;
  });
});

希望它有所帮助。 达里奥

答案 1 :(得分:0)

您正在阅读的最佳实践绝对正确,您应该将所有服务器通信放在一个单独的模块中,这将使所有工厂在那里进行服务器交换。

然后你可以注入这个,假设集成模块和服务器通信所需的所有工厂都可用。

现在,样本工厂可以是:

angular.module('integrationModule')
.factory('ItemsFactory',function($http){
  return {
    getItems: function() {
      return $http.get('js/items.json');
    }
  };
});

app.controller('ListCtrl', function($scope, ItemsFactory) {
  ItemsFactory.getItems().then(function(res){
    $scope.items = res.data;
  });
});
//credits Dario

或者这是我的首选方式(此处不需要承诺)

angular.module('integrationModule')
    .factory('getLocaleProperties', ['$http', function($http) {     
        return function(requestObj, callBackFunc){
            console.log('@getLocaleProperties:');
            console.log(requestObj);
            $http.get('assets/locale/localeProperties.json')
            .success(function(data) {
                callBackFunc(data);
            })
            .error(function(){
                console.log('error in get Locale properties');
            });
        }
    }])

现在,如果您注意到,我正在传递回调函数,该函数仅在$ http调用成功时执行,因此在控制器中您可以注入此工厂并传递一些函数,如:

getLocaleProperties({//some request object when posting/as query params in url}, function(data){
 //do some operation on the data
})

这样我可以从不同的控制器调用工厂,并在调用成功时执行不同的操作。我需要传递不同的回调函数。

你也可以使用promise,就像你正在做的那样,但只有当你想要一个像行为一样的同步调用时才需要它们,休息可以做回调。($ http调用在角度源代码中指定async)。

希望这有帮助。