Angular 抛出错误的 Http 请求服务

Http request service with Angular throwing an error

我正在尝试编写一个向我的路由 (NodeJs) 发出 http 请求以将用户添加到数据库的服务。

如果我只是将它写在控制器中它就可以工作,但是在我刷新浏览器之前你不会看到用户被添加:

我在控制器中的代码:

//Function to add a user to the db
$scope.inviteUser = function(){
    $http.post('/api/users/invite', {
        'email': $scope.user.email,
        'role_id': $scope.user.role
    }, {
        headers: {
            "Content-Type": "text/plain"
        }
    })
    .success(function(data, status, headers, config) {
        console.log("Successfully saved a user to the DB", data);

        $scope.userInfo.push(data);


    })
    .error(function(data, status, headers, config) {
        console.log("Failed to add user to DB");
    });
}

我在服务中需要它的原因是因为堆栈上的人告诉我它可以解决我当前面临的问题,即添加用户时您将在浏览器刷新之前看不到它。这是因为我有一个带有按钮邀请的视图,当您单击它时会显示一个弹出窗口 (md-dialog -> angular material)。此对话框有自己的 tmple.html 文件。在邀请按钮所在的视图中,$scope.userInfo linked 到(在函数 inviteUser 中定义 - 上面的代码)

带有邀请按钮的视图代码和添加用户的列表:

<div id="sidebar" class="md-whiteframe-z4" ng-data-color="">
      <div style="height: 80px;"></div>
      <div class="userList">
        <li id="customLI" ng-repeat="user in userInfo" id="userPos" class="circular md-whiteframe-z2" style="background-color: {{ user.color }} " ng-click=" showPopUpDeletionConfirmation(); setDeleteId( user._id )" ng-data-id="{{ user._id }} ">
          <p class="initials" id="userValue" style="top: {{ user.top }};" >
              <custom id="user._id"></custom>
              {{user.initials}}
          </p>
        <md-tooltip>
        <!-- Delete this user -->  {{user.name}}
        </md-tooltip>
        </li>
      </div>
    </div>

对话框代码:

  <md-dialog aria-label="" ng-controller="CalendarCtrl">
    <form name="form"  >
      <md-toolbar>
        <div class="md-toolbar-tools">
          <h1 class="customH1">Invite a user</h1>

          <span flex></span>
          <!-- <md-button class="md-icon-button" ng-click="closeDialog()">
            <md-icon md-svg-src="images/ic_close_24px.svg" aria-label="Close dialog"></md-icon>
          </md-button> -->
        </div>
      </md-toolbar>
      <md-dialog-content>
        <div id="containerForm">
            <div layout="row">
              <md-input-container flex="">
                <div class="form-group" ng-class="{ 'has-success': form.email.$valid && submitted,'has-error': form.email.$invalid && submitted }">
                  <label>Enter the user's e-mail</label>
                  <input type="email" name="email" id="to" class="form-control" ng-model="user.email" required mongoose-error/>
                  <p class="help-block" ng-show="form.email.$error.email && submitted">
                    Doesn't look like a valid email.
                  </p>
                  <p class="help-block" ng-show="form.email.$error.required && submitted">
                    What's your email address?
                  </p>
                  <p class="help-block" ng-show="form.email.$error.mongoose">
                    {{ errors.email }}
                  </p>
                </div>
              </md-input-container>
            </div>  

            <br /><br />

            <div ng-show="form.email.$dirty && form.email.$valid">
              <h5>Assign one of the following role's:</h5>

              <div id="wrapperRadioButtons">
                <md-radio-group ng-model="user.role">
                  <md-radio-button ng-repeat="userrole in roleInfo" value="{{userrole.id}}" class="md-primary">{{userrole.role}}</md-radio-button>
                </md-radio-group>
              </div>
              </div>

            <br />

        </div>
      </md-dialog-content>
      <div class="md-actions" layout="row" >
        <md-button ng-click="closeDialog()" class="md-primary">Cancel</md-button>

        <md-button id="send_email" ng-click="inviteUser(); closeDialog()" class="md-primary">Invite</md-button>
      </div>
    </form>
  </md-dialog>

这是我编写并尝试 link 函数 inviteUsers:

的服务
zazzleApp.factory('UserService', ['$q', '$http', function ($q, $http) {
            var service = {};

            service.get = function() {
              var deferred = $q.defer();

              deferred.resolve(service.data);
              return deferred.promise;
            }

            service.save = function(data) {
                var promise = $http({
                    method: 'POST',
                    url: 'api/users/invite'
                })

                var deferred = $q.defer();

                service.data.push(data);
                deferred.resolve();
                return deferred.promise;
            }

            return service;
        }
    ]);

我的部分控制器:

angular.module('zazzleToolPlannerApp')
    .controller('CalendarCtrl', function ($scope, $mdDialog, $http, $rootScope, $timeout, User, Auth, UserService) {

        //Function to add a user to the db
        $scope.inviteUser = function(){

           var obj = {
                'email': $scope.user.email,
                'role_id': $scope.user.role
           };
           UserService.save(obj).then(function(){
                $scope.getUsers();

           })
        }
});

现在,当我尝试添加用户时,我的控制台出现错误 -> https://gyazo.com/34b39d7eda18b8afd9ef11094b4f429a

所以基本上我要问的是如何编写一个服务来发出 http 请求并将其 link 发送到控制器....

旁注:我以前从未这样做过,所以这就是它可能不起作用的原因。

我只能看到你的日志中写着

typeError can not read property 'push' of undefined at object.service.save

我认为这与您的 HTTP 请求没有任何关系。 你还没有定义你的service.data.push(data);,那是他转储的地方

尝试将 service 对象的 data 属性 定义为数组,然后再将值推送给它(它还不知道它是一个数组,因此它无法访问数组原型函数)

这样做

service = { data: [] };

希望对您有所帮助。

您在控制台中收到错误的原因是 service.dataservice.data.push(data); 中不存在。您的意思可能是将新用户推送到尚未创建的用户数组中(您似乎对 code:P 中的 "data" 感到困惑)。

无论如何,你的问题的解决方案要简单得多: 在服务中,您可以 return $http.post() 到控制器并在 .success() 回调中处理控制器中的请求。此外,您需要更新的用户列表应该驻留在服务中,您可以从控制器绑定到它;这样,在您添加新用户后无需刷新浏览器,模板就会保持更新。您只需从服务的 $http 回调中检索用户列表。

如果您仍然觉得这很困惑,我可以写一个fiddle。

编辑:这里是fiddle:http://jsfiddle.net/bosch/8pnL23k7/。希望它能帮助你更好地理解这些概念