MEAN堆栈和ngResource - 不了解如何传递url资源ID

时间:2014-12-28 20:36:53

标签: angularjs express mean-stack ngresource

我正在尝试用平均堆栈构建一个小应用程序,我几天来一直在努力解决这个问题。该应用程序非常简单,我可以创建Quizes,然后创建与这些quizes有关的问题。

不同的REST URL如下:

/api/quizes
/api/quizes/:quizId
/api/quizes/:quizId/questions
/api/quizes/:quizId/questions/:questionId

我可以列出不同的quizes,添加,编辑和删除它们没有问题。但是,我在“查看测验”视图中有一个“添加问题”链接,该链接会将我重定向到“添加问题视图”并向我显示一个表单。当我提交此表单时,我从服务器收到错误404.

Chrome中的“网络”标签显示POST是 / quizes / questions 网址,这当然不正确:

POST http://localhost:3000/api/quizes/questions 404 (Not Found)

我注意到它尝试POST的网址是:

/api/quizes/questions

应该是:

/api/quizes/:quizId/questions 

我不明白为什么它没有拾取quizId,因为当我在“创建问题视图”中填写表单时,url是正确的并且包含quizId:

http://localhost:3000/#!/quizes/5483e94168bff98c17e1d120/questions/create

一点代码:

我的问题服务(我认为问题就在那里):

'use strict';

angular.module('questions').factory('Questions', ['$resource', function($resource) {
  return $resource('api/quizes/:quizId/questions/:questionId', {
    quizId: '@_id',
    questionId: '@quizId'
  }, {
    update: {
      method: 'PUT'
    }
  });
}]);

问题客户端控制器(我刚把相关代码放在这里):

'use strict';
angular.module('questions').controller('QuestionsController', ['$scope', '$routeParams', '$location', 'Authentication', 'Questions', 'Quizes',
  function($scope, $routeParams, $location, Authentication, Questions, Quizes) {
    $scope.authentication = Authentication;
    $scope.create = function() {
      var question = new Questions({
        value: this.value,
        type: this.type,
        answer: this.answer
      });

      question.$save(function(response) {
        $location.path('quizes/:quizId/questions/' + response._id);
      }, function(errorResponse) {
        $scope.error = errorResponse.data.message;
      });
    };

问题客户路线:

'use strict';
angular.module('questions').config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
    when('/quizes/:quizId/questions', {
      templateUrl: 'questions/views/list-questions.client.view.html'
    }).
    when('/quizes/:quizId/questions/create', {
      templateUrl: 'questions/views/create-question.client.view.html'
    }).
    when('/quizes/:quizId/questions/:questionId', {
      templateUrl: 'questions/views/view-question.client.view.html'
    }).
    when('/quizes/:quizId/questions/:questionId/edit', {
      templateUrl: 'questions/views/edit-question.client.view.html'
    });
  }
]);

最后,创建问题视图:

<section data-ng-controller="QuestionsController">
<h1>New Question</h1>
  <form data-ng-submit="create()" novalidate>
    <div>
      <label for="value">Value</label>
      <div>
        <input type="text" data-ng-model="value" id="value" placeholder="Value" required>
      </div>
    </div>
    <div>
      <label for="type">Type</label>
      <div>
        <input type="text" data-ng-model="type" id="type" placeholder="Type" required>
      </div>
    </div>
    <div>
      <label for="answer">Answer</label>
      <div>
        <textarea data-ng-model="answer" id="answer" cols="30" rows="10" placeholder="Answer"></textarea>
      </div>
    </div>
    <div>
      <input type="submit">
    </div>
    <div data-ng-show="error">
      <strong data-ng-bind="error"></strong>
    </div>
  </form>
</section>

我认为这个问题不在服务器端,但这里是问题服务器控制器(我在这里删除了不相关的代码):

var mongoose = require('mongoose'),
    Question = mongoose.model('Question');

var getErrorMessage = function(err) {
  if (err.errors) {
    for (var errName in err.errors) {
      if (err.errors[errName].message) return err.errors[errName].message;
    }
  } else {
    return 'Unknown server error';
  }
};

exports.create = function(req, res) {
  var question = new Question(req.body);
  question.creator = req.user;
  question.quiz = req.quiz;

  question.save(function(err) {
    if (err) {
      return res.status(400).send({
        message: getErrorMessage(err)
      });
    } else {
      res.json(question);
    }
  });
};

服务器端的模型:

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var QuestionSchema = new Schema({
  created: {
    type: Date,
    default: Date.now
  },
  value: {
    type: String,
    default: '',
    trim: true,
    required: 'Value cannot be blank'
  },
  type: {
    type: String,
    default: '',
    trim: true,
    required: 'Type cannot be blank'
  },
  answer: {
    type: String,
    default: '',
    trim: true,
    required: 'Answer cannot be blank'
  },
  quiz: {
    type: Schema.ObjectId,
    ref: 'Quiz'
  },
  creator: {
    type: Schema.ObjectId,
    ref: 'User'
  }
});

mongoose.model('Question', QuestionSchema);

最后我的问题在服务器端路由:

var users = require('../../app/controllers/users.server.controller'),
    questions = require('../../app/controllers/questions.server.controller'),
    quizes = require('../../app/controllers/quizes.server.controller');

module.exports = function(app) {
  app.route('/api/quiz/:quizId/questions')
     .get(questions.list)
     .post(users.requiresLogin, questions.create);

  app.route('/api/quizes/:quizId/questions/:questionId')
     .get(questions.read)
     .put(users.requiresLogin, questions.hasAuthorization, questions.update)
     .delete(users.requiresLogin, questions.hasAuthorization, questions.delete);

  app.param('quizId', quizes.quizByID);
  app.param('questionId', questions.questionByID);

};

1 个答案:

答案 0 :(得分:1)

在评论中讨论后,我认为提出的问题有三个:

  1. 问题资源将quizId默认为null,这会使您的请求看起来像这样:api/quizes/questions让我们解决这个问题:

    return $resource('api/quizes/:quizId/questions/:questionId', {
        questionId: '@_id',
        quizId: '@quiz'
        }, {
        update: {
            method: 'PUT'
        }
    
  2. 然后当你保存新问题时,从$ routeParams传递quizId:

    newQuestion.$save({quizId: $routeParams.quizId} , function() {
        $scope.questions.push(newQuestion)
    })
    
    1. 服务器路由期待发送请求/api/quiz' and that's why you get 404 , because the server doesn't have a route for post requests to / api / quizes / ..`
    2. 通过更改服务器中的此行来解决此问题:

       app.route('/api/quizes/:quizId/questions') //   
      
      1. $ location.path不接受路径中的变量,而是$location.path('quizes/'+$routePrams.quizId+'/questions/' + response._id)
      2. 希望这有帮助