2014-12-07 55 views
-1

我正在构建一个接受来自表单的输入(输入是名称)的小应用程序,然后继续使用$ httpBackend将该名称发布到模拟web服务。在POST之后,我还使用$ httpBackend从模拟web服务执行GET,然后获取使用POST设置的名称/变量。从服务中获得简单的问候语后,客户端就会构建并显示出来。在AngularJS中未定义

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

我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> 
+0

功能的getName() - >这应该是一个真正的AngularJS服务,依赖注入。现在一切都是你的控制器,这在ANgular的世界里是一个糟糕的坏主意。 – 2014-12-07 12:20:08

+0

对不起,我是Angular的新手,我不确定你的意思是“善意”吗?你是说我应该将'setName'和'getName'函数提取到另一个单独的文件中? – Tiwaz89 2014-12-07 12:27:51

+1

谷歌是你的朋友:-) http://www.thefreedictionary.com/bona+fide AngularJS服务是单身人士,更适合任何CRUD。 [http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory-with-example/](http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory -with-example /) - 一个单独的文件,如果你愿意。主要是显式创建/声明一个服务,您可以使用DI导入您的控制器。在您的服务中创建/ interface_your_API,编写您需要的任何CRUD功能,然后将其返回。您的承诺可能在服务(最佳)或控制器中。 – 2014-12-07 12:30:34

回答

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()成服务的方式。

+0

非常感谢您花时间和帮助我:)但它现在返回的是[Object Object] – Tiwaz89 2014-12-07 13:00:22

+0

我不知道您的服务返回的是什么。您可以在成功处理程序中将'data'记录到控制台,以查看返回的内容并相应地转换结果(提取名称)。您可以在$ http:https://docs.angularjs.org/api/ng/service/$http的文档中阅读更多内容 – JohnDoe90 2014-12-07 13:14:37

0

您不能从异步调用中返回常规变量,因为当这个成功块被执行时,函数已经完成了迭代。 您需要返回一个承诺对象(作为指导,并从服务中进行优化)。

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

以下文章为$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 
     }) 
    } 
}]);