在AngularJS中获取未定义

时间:2014-12-07 12:16:03

标签: javascript angularjs

我正在构建一个接受表单输入的小应用程序(输入是名称)然后继续使用$ httpBackend将名称POST到模拟Web服务。在POST之后,我还使用$ httpBackend从模拟Web服务进行GET,然后获取使用POST设置的名称/变量。从服务中获取后,构建一个简单的问候语并显示在客户端。

但是,目前当数据现在显示回客户端时,它会显示“Hello undefined!”什么时候应该读“你好[无论你输入什么名字]!”。我使用Yeoman来做我的app脚手架,所以我希望每个人都能理解我的文件和目录结构。

我的app.js:

'use strict';

angular
  .module('sayHiApp', [
    'ngCookies',
    'ngMockE2E',
    'ngResource',
    'ngSanitize',
    'ngRoute'
  ])
  .config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  })
  .run(function($httpBackend) {

    var name = 'Default Name';

    $httpBackend.whenPOST('/name').respond(function(method, url, data) {

      //name = angular.fromJson(data);
      name = data;

      return [200, name, {}];
    });

    $httpBackend.whenGET('/name').respond(name);

    // Tell httpBackend to ignore GET requests to our templates
    $httpBackend.whenGET(/\.html$/).passThrough();

  });

我的main.js:

'use strict';

angular.module('sayHiApp')
  .controller('MainCtrl', function ($scope, $http) {

    // Accepts form input
    $scope.submit = function() {

      // POSTS data to webservice
      setName($scope.input);

      // GET data from webservice
      var name = getName();

      // Construct greeting
      $scope.greeting = 'Hello ' + name + ' !';

    };

    function setName (dataToPost) {

      $http.post('/name', dataToPost).
      success(function(data) {
        $scope.error = false;
        return data;
      }).
      error(function(data) {

        $scope.error = true;
        return data;
      });
    }

    // GET name from webservice
    function getName () {

      $http.get('/name').
      success(function(data) {

        $scope.error = false;
        return data;
      }).
      error(function(data) {

        $scope.error = true;
        return data;
      });

    }

  });

我的main.html:

<div class="row text-center">
    <div class="col-xs-12 col-md-6 col-md-offset-3">

        <img src="../images/SayHi.png" class="logo" />

    </div>
</div>

<div class="row text-center">
    <div class="col-xs-10 col-xs-offset-1 col-md-4 col-md-offset-4">

        <form role="form" name="greeting-form" ng-Submit="submit()">
            <input type="text" class="form-control input-field" name="name-field" placeholder="Your Name" ng-model="input">
            <button type="submit" class="btn btn-default button">Greet Me!</button>
        </form>

    </div>
</div>

<div class="row text-center">
    <div class="col-xs-12 col-md-6 col-md-offset-3">

        <p class="greeting">{{greeting}}</p>

    </div>
</div>

2 个答案:

答案 0 :(得分:1)

目前,getName()方法没有返回任何内容。你也不能只调用getName()并期望结果在函数调用之后立即可用,因为$http.get()是异步运行的。 你应该尝试这样的事情:

function getName () {
  //return the Promise
  return $http.get('/name').success(function(data) {
    $scope.error = false;
    return data;
  }).error(function(data) {
    $scope.error = true;
    return data;
  });
}

$scope.submit = function() {
  setName($scope.input);
  //wait for the Promise to be resolved and then update the view
  getName().then(function(name) {
    $scope.greeting = 'Hello ' + name + ' !';
  });
};

顺便说一下,您应该将getName(), setName()放入服务中。

答案 1 :(得分:0)

您无法从异步调用返回常规变量,因为在此成功块被执行时,该函数已完成迭代。 您需要返回一个promise对象(作为指导,并优先从服务中执行)。

我不会修复您的代码,但我会与您分享必要的工具 - 承诺。

按照$q$http的角度文档,您可以为自己构建异步调用处理模板。

模板应该是这样的:

angular.module('mymodule').factory('MyAsyncService', function($q, http) {

var service = {
    getNames: function() {
        var params ={};
        var deferObject = $q.defer();
        params.nameId = 1;
        $http.get('/names', params).success(function(data) {
            deferObject.resolve(data)
        }).error(function(error) {
            deferObject.reject(error)
        });

        return $q.promise;
    }
}
});

angular.module('mymodule').controller('MyGettingNameCtrl', ['$scope', 'MyAsyncService', function ($scope, MyAsyncService) {

    $scope.getName = function() {
        MyAsyncService.getName().then(function(data) {
            //do something with name
        }, function(error) {
            //Error 
        })
    }
}]);