Angular: Passing data back to my controller from a

2019-07-19 02:36发布

问题:

I've been playing with Angular and I've moved from working with local data (which seems to work fine) to trying to populate my view from an ajax call in my factory.

Here's the code:

    <html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.17/angular.min.js"></script>
</head>
<body>
<div ng-app="testApp">
  <h2>Get data using a Factory</h2>
    <div ng-controller="simpleController">

    <input type="text" placeholder="Filter" ng-model="name">

    <ul>
      <li ng-repeat="person in family | filter:name">[{{$index + 1}}] {{person.name}} - {{person.age}}</li>
    </ul>

  </div>
</div>
<script>
// our very, very simple controller - on the page itself
var testApp = angular.module('testApp', []);

testApp.factory('simpleFactory', function($http) {
  var family = [
    {name: 'Joe', age: 40},
    {name: 'Maryellen', age: 37},
    {name: 'Isaac', age: 12},
    {name: 'Emilie-Alice', age: 14}
  ];

  var factory = {};
  factory.getFamily = function() {
    return family;
  }

  factory.getFamily2 = function() {
    $http.get('/family.json').then(function(result) {
      family = result.data;
      console.log(family); // I see the objects! 
      return family; // this doesn't return the data like getFamily() does - why???
    });
  }

  return factory;
});

testApp.controller('simpleController', function($scope, simpleFactory) {
  $scope.family = [];

  init();

  function init() {
    $scope.family = simpleFactory.getFamily2();
  }
});
</script>
</body>
</html>

Everything seems okay, I can see the json data in my console log, but "return family" doesn't get the data to $scope.family

What am I missing? I know it has to be something simple.

Thanks!

回答1:

To completely abstract the data handling into the factory, you can both return the promise from $http and leave the return inside the .then():

factory.getFamily2 = function() {
    return $http.get('/family.json').then(function(result) {
      family = result.data;
      console.log(family); // I see the objects! 
      return family; // this doesn't return the data like getFamily() does - why???
    });
  }

function init() {
    simpleFactory.getFamily2().then(function(data){
        $scope.family = data;
    }); 

This ensures the controller calling the factory method will get the data when it's ready. You can also handle error checking, etc, inside the factory and not in the controller, completely separating concerns.



回答2:

The answer of sitesbyjoe is fine, but... you don't need the first assignation in controller (line 2 of 2nd block code), only calling to the function and assign a value inside is enogh

Factory

factory.getFamily2 = function() {
    return $http.get('/family.json').then(function(result) {
      family = result.data;
      return family;
    });
  }

In Controller

 function init() {
    simpleFactory.getFamily2().then(function(data) {
        $scope.family = data;
    });
  }


回答3:

FYI - What I ended up changing in the factory:

factory.getFamily2 = function() {
    return $http.get('/family.json').then(function(result) {
      family = result.data;
      return family;
    });
  }

and in the controller:

function init() {
    $scope.family = simpleFactory.getFamily2().then(function(data) {
        $scope.family = data;
    });
  }

With these changes in place I get the remote data, the view filtering works fine, and all is well.