You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 1.6.6:控制器$http迁移至Factory后$scope数据绑定异常

Fixing Angular 1.6.6 Data Binding Issue After Moving $http to Factory

Hey there, I can spot the issue right away—you're running into a common pitfall with Promises in Angular, and your controller isn't properly handling the Promise returned by your Factory. Let's fix this together!

What's Going Wrong

When you moved your $http call to the Factory, you’re returning a Promise from getAllDBRegions(), but in your controller, you’re directly assigning that Promise to $scope.regions instead of waiting for it to resolve and extracting the actual data. Angular can’t bind a Promise object to your view, which is why you see the data in the debugger but it doesn’t show up in your template.

Also, a quick cleanup: you don’t need to manually create a $q.defer() here—$http already returns a Promise, so we can simplify your Factory code to avoid that anti-pattern.

Step 1: Simplify the Factory Code

Let’s rewrite the Factory to return the $http Promise directly, and make sure we pass the correct data when resolving:

angular.module('randomTown.service', [])
.factory('randomTownFactory', function ($http) {
  var service = {};

  service.getAllDBRegions = function() {
    // $http already returns a Promise, no need for $q.defer()
    return $http({
      method: 'GET',
      url: '/all-regions'
    }).then(function success(response) {
      // Return the actual data (response.data) instead of the full response object
      return response.data;
    }, function error(response) {
      // Reject with a meaningful error message
      return Promise.reject('There was an error fetching regions: ' + response.statusText);
    });
  };

  return service;
});

Step 2: Fix the Controller to Handle the Promise

Now update your controller to wait for the Promise to resolve before assigning data to $scope.regions:

angular.module('randomTown.controller', [])
.component('randomTownGenerator', { 
  templateUrl: 'js/components/randomTownGenerator/randomTownGenerator.tpl.html' 
})
.controller('RandomTownCtrl', function($scope, randomTownFactory) { 
  $scope.data = {}; 

  $scope.getAllRegions = function () {
    // Call the Factory method, then handle the resolved Promise
    randomTownFactory.getAllDBRegions()
      .then(function(regionsData) {
        // Assign the actual data to $scope.regions
        $scope.regions = regionsData;
      })
      .catch(function(error) {
        // Handle any errors here (optional but recommended)
        console.error(error);
      });
  };
});

Why This Works

  • The Factory now returns the $http Promise directly, which is cleaner and avoids unnecessary $q usage.
  • In the controller, we use .then() to wait for the Promise to successfully resolve, then assign the actual region data to $scope.regions. This ensures the data is available when Angular goes to bind it to your template.
  • We also added a .catch() block to handle errors, which is a good practice for debugging and user feedback.

Your template doesn’t need any changes—once $scope.regions is populated with the actual array of region objects, ng-options will render the options correctly.

内容的提问来源于stack exchange,提问作者Nate Anderson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:31:34