Javascript 将角度控制器重构为独立的工厂和控制器

Javascript 将角度控制器重构为独立的工厂和控制器,javascript,angularjs,http,dependency-injection,angular-promise,Javascript,Angularjs,Http,Dependency Injection,Angular Promise,学习角度。立即使用1.6.6 在我最初的尝试中,我将所有的$http请求放入我的控制器中,因此我尝试将其从控制器中取出并放入工厂,以获得更多可重用的代码。我认为我缺少了一些与承诺或注入相关的内容,但是我的$http调用中的数据没有正确绑定到$scope 我有一个从控制器开始加载的模板(模板加载良好): 服务: angular. module('randomTown.service', []). factory('randomTownFactory', function ($q,

学习角度。立即使用
1.6.6

在我最初的尝试中,我将所有的
$http
请求放入我的控制器中,因此我尝试将其从控制器中取出并放入工厂,以获得更多可重用的代码。我认为我缺少了一些与
承诺
或注入相关的内容,但是我的
$http
调用中的数据没有正确绑定到
$scope

我有一个从控制器开始加载的模板(模板加载良好):

服务:

angular.
    module('randomTown.service', []).
    factory('randomTownFactory', function ($q, $http) {

        var service = {};

        service.getAllDBRegions = function() {

            var deferred = $q.defer();

            $http({
                  method: 'GET',
                  url: '/all-regions'
            }).then(function success(data) {
                deferred.resolve(data);
            }), function error(response) {
                deferred.reject('There was an error');
            }

            return deferred.promise;
        }

        return service;
    }); 
试试这个:

$scope.getAllRegions = function () {
            randomTownFactory.getAllDBRegions()
            .then((regions) => {$scope.regions = regions});
        }

原因:因为
etAllDBRegion
s返回一个承诺,所以您必须使用
then
属性来获得结果

,因此无需使用
$q.defer
创建承诺。只需返回
$http
承诺:

app.factory('randomTownFactory', function ($q, $http) {

    var service = {};

    service.getAllDBRegions = function() {

        ̶v̶a̶r̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶

        ̲r̲e̲t̲u̲r̲n̲ $http({
              method: 'GET',
              url: '/all-regions'
        }).then(function success( ̶d̶a̶t̶a̶ response) {
            ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶r̶e̶s̶o̶l̶v̶e̶(̶d̶a̶t̶a̶)̶;̶
            return response.data;
        }),̶ ̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶e̶r̶r̶o̶r̶(̶r̶e̶s̶p̶o̶n̶s̶e̶)̶ ̶{̶

           ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶r̶e̶j̶e̶c̶t̶(̶'̶T̶h̶e̶r̶e̶ ̶w̶a̶s̶ ̶a̶n̶ ̶e̶r̶r̶o̶r̶'̶)̶;̶
        ̶}̶
          ̶r̶e̶t̶u̶r̶n̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶p̶r̶o̶m̶i̶s̶e̶;̶, 
    }

    return service;
}); 
还要注意,
success
处理程序不会显示
数据。它显示一个
响应
对象,其中
数据
是该对象的属性之一

控制员:

app.controller('RandomTownCtrl',

    function($scope, randomTownFactory) {

        $scope.getAllRegions = function () {
            var promise = randomTownFactory.getAllDBRegions();
            promise.then(function(data) {
                $scope.regions = data;
            }).catch(function(errorResponse) {
                console.log("ERROR", errorResponse.status)
            });          
        }

    }
);  
有关详细信息,请参阅


我实现了你的建议,现在我在下拉列表中得到了我想要的东西,但是所有的值都是未定义的。我可以看到
区域中的数据是正确的,但似乎绑定到
$scope
的工作并不像我预期的那样正常。@NateAnderson-您的选项为空:
。尝试记录
区域
内部
然后
并检查内部
然后
区域正是我所期望的。我的理解是,
ng options=“item.guidEntity as item.nameEntity for item in regions”
可以满足
values=“
。当
$http
调用在控制器中并且数据被直接绑定时,@NateAnderson我不是很确定,但是在文档中没有这样的例子:尝试删除这一行。如果您必须使用
ng if
我建议使用
nr repeat
而不是
ng选项
app.factory('randomTownFactory', function ($q, $http) {

    var service = {};

    service.getAllDBRegions = function() {

        ̶v̶a̶r̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶ ̶=̶ ̶$̶q̶.̶d̶e̶f̶e̶r̶(̶)̶;̶

        ̲r̲e̲t̲u̲r̲n̲ $http({
              method: 'GET',
              url: '/all-regions'
        }).then(function success( ̶d̶a̶t̶a̶ response) {
            ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶r̶e̶s̶o̶l̶v̶e̶(̶d̶a̶t̶a̶)̶;̶
            return response.data;
        }),̶ ̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶e̶r̶r̶o̶r̶(̶r̶e̶s̶p̶o̶n̶s̶e̶)̶ ̶{̶

           ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶r̶e̶j̶e̶c̶t̶(̶'̶T̶h̶e̶r̶e̶ ̶w̶a̶s̶ ̶a̶n̶ ̶e̶r̶r̶o̶r̶'̶)̶;̶
        ̶}̶
          ̶r̶e̶t̶u̶r̶n̶ ̶d̶e̶f̶e̶r̶r̶e̶d̶.̶p̶r̶o̶m̶i̶s̶e̶;̶, 
    }

    return service;
}); 
app.controller('RandomTownCtrl',

    function($scope, randomTownFactory) {

        $scope.getAllRegions = function () {
            var promise = randomTownFactory.getAllDBRegions();
            promise.then(function(data) {
                $scope.regions = data;
            }).catch(function(errorResponse) {
                console.log("ERROR", errorResponse.status)
            });          
        }

    }
);