我正在创建一个MEAN堆栈应用,而且我一直在使用这本书“均值网络开发”#39;由Amos Q. Haviv帮助我。我遇到了一个问题,我有一个假设提交食谱的表单,但当我检查数据库时,条目是id,date和author但没有title,mainImage,content,category或tags 。在过去的几天里,我一直试图自己解决这个问题并再次看完这本书,看看我是否犯过任何错误,但没有运气。
这是我的模特:
// Load the module dependencies
var mongoose = require('mongoose'),
paginator = require('mongoose-paginator'),
Schema = mongoose.Schema;
var CommentsSchema = new Schema({
commentor: String,
data: {
type: Date,
default: Date.now()
},
content: {
type: String,
default: ' ',
trim: true,
required: "Enter a comment into the comment box"
},
agree: Number,
disagree: Number
});
function toLower(lowerText) {
return lowerText.toLowerCase();
}
var TagsSchema = new Schema({
tags: {
type: String,
set: toLower
}
});
var RecipeSchema = new Schema({
created: {
type: Date,
default: Date.now()
},
author: {
type: Schema.ObjectId,
ref: 'User'
},
title: {
type: String,
default: ' ',
trim: true,
required: 'Title cannot be blank'
},
mainImage: {
type: String,
default: ' ',
trim: true
},
content: {
type: String,
default: ' ',
trim: true,
required: "Please enter recipe"
},
likes: Number,
faves: Number,
category: {
type: String,
set: toLower
},
tags: [TagsSchema],
comments: [CommentsSchema]
});
// Use paginator
RecipeSchema.plugin(paginator, {
limit: 20,
defaultKey: '_id',
direction: 1
});
mongoose.model('Recipe', RecipeSchema);
这是我的控制器
// Load the module dependencies
var mongoose = require('mongoose'),
Recipe = mongoose.model('Recipe');
// Create a new error handling controller
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';
}
};
// Create a new controller method that creates a new recipe
exports.create = function(req, res) {
// Create a new recipe object
var recipe = new Recipe(req.body);
// Set the recipe's 'author' property
recipe.author = req.user;
// Try saving the recipe
recipe.save(function(err) {
if (err) {
// If an error occurs send the error message
return res.status(400).send({
message: getErrorMessage(err)
});
}else {
// Send a JSON representation of the recipe
res.json(recipe);
}
});
};
// Create a new controller method that retrieves a list of recipes
exports.list = function(req, res) {
// User the model 'find' method to get a list of recipes
Recipe.find().sort('-created').populate('author', 'username userName').exec(function(err, recipes) {
if (err) {
// If an error occurs send the error message
return res.status(400).send({
message: getErrorMessage(err)
});
} else {
// Send a JSON representation of the article
res.json(recipes);
}
});
};
// Create a new controller method that returns an existing recipe
exports.read = function(req, res) {
res.json(req.recipe);
}
// Create a new controller method that updates an existing recipe
exports.update = function(req, res) {
// Get the recipe from the 'request' object
var recipe = req.recipe;
// Update the recipe fields
recipe.title = req.body.title;
recipe.mainImage = req.body.mainImage;
recipe.content = req.body.content;
recipe.category = req.body.category;
recipe.tags = req.body.tags;
// Try saving the updated recipe
recipe.save(function(err) {
if (err) {
// If an error occurs send the error message
return res.status(400).send({
message: getErrorMessage(err)
});
} else {
// Send a JSON representation of the recipe
res.json(recipe);
}
});
};
// Create a new controller method that deletes an existing recipe
exports.delete = function(req, res) {
// Get the recipe from the 'request' object
var recipe = req.recipe;
// Use the model 'remove' method to delete the recipe
recipe.remove(function(err) {
if (err) {
// If an error occurs send the error message
return res.status(400).send({
message: getErrorMessage(err)
});
} else {
// Send a JSON representation of the recipe
res.json(recipe);
}
});
};
// Create a new controller middleware that retrieves a single existing recipe
exports.recipeByID = function(req, res, next, id) {
// Use the model 'findById' method to find a single recipe
Recipe.findById(id).populate('author', 'username userName').exec(function(err, recipe) {
if (err) return next(err);
if (!recipe) return next(new Error('Failed to load recipe ' + id));
// If an recipe is found use the 'request' object to pass it to the next middleware
req.recipe = recipe;
// Call the next middleware
next();
});
};
// Create a new controller middleware that is used to authorize an recipe operation
exports.hasAuthorization = function(req, res, next) {
// If the current user is not the author of the recipe send the appropriate error message
if (req.recipe.author.id !== req.user.id) {
return res.status(403).send({
message: 'User is not authorized'
});
}
// Call the next middleware
next();
};
这是express.js
// Load the module dependencies
var config = require('./config'),
http = require('http'),
express = require('express'),
morgan = require('morgan'),
compress = require('compression'),
bodyParser = require('body-parser'),
methodOverride = require('method-override'),
session = require('express-session'),
MongoStore = require('connect-mongo')(session),
flash = require('connect-flash'),
passport = require('passport');
// Define the Express configuration method
module.exports = function(db) {
// Create a new Express appllication instance
var app = express();
// Create a new HTTP server
var server = http.createServer(app);
// Use the 'NDOE_ENV' variable to activate the 'morgan' logger or 'compress' middleware
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'));
} else if (process.env.NODE_ENV === 'production') {
app.use(compress());
}
// Use the 'body-parser' and 'method-override' middleware functions
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json({ type: 'application/*+json' }));
app.use(methodOverride('X-HTTP-Method-Override'));
// Configure the MongoDB session storage
var mongoStore = new MongoStore({
db: db.connection.db
});
// Configure the 'session' middleware
app.use(session({
saveUninitialized: true,
resave: true,
secret: config.sessionSecret
}));
// Set the application view engine and 'views' folder
app.set('views', './app/views');
app.set('view engine', 'ejs');
// Configure the flash messages middleware
app.use(flash());
// Configure the Passport middleware
app.use(passport.initialize());
app.use(passport.session());
// Load the routing files
require('../app/routes/index.server.routes.js')(app);
require('../app/routes/users.server.routes.js')(app);
require('../app/routes/recipes.server.routes.js')(app);
// Configure static file serving
app.use(express.static('./public'));
// Return the Server instance
return server;
};
AngularJS食谱控制器
// Invoke 'strict' JavaScript mode
'use strict';
// Create the 'recipes' controller
angular.module('recipes').controller('RecipesController', ['$scope', '$routeParams', '$location', 'Authentication', 'Recipe',
function($scope, $routeParams, $location, Authentication, Recipe) {
// Expose the Authentication service
$scope.authentication = Authentication;
// Create a new controller method for creating new recipes
$scope.create = function() {
// Use the form fields to create a new recipe $resource object
var recipe = new Recipe({
title: this.title,
mainImage: this.mainImage,
content: this.content,
category: this.category,
tags: this.tags
});
// Use the recipe '$save' method to send an appropriate POST request
recipe.$save(function(response) {
// If an recipe was created successfully, redirect the user to the recipe's page
$location.path('recipes/' + response._id);
}, function(errorResponse) {
// Otherwise, present the user with the error message
$scope.error = errorResponse.data.message;
});
};
// Create a new controller method for retrieving a list of recipes
$scope.find = function() {
// Use the recipe 'query' method to send an appropriate GET request
$scope.recipes = Recipe.query();
};
// Create a new controller method for retrieving a single recipe
$scope.findOne = function() {
// Use the recipe 'get' method to send an appropriate GET request
$scope.recipe = Recipe.get({
recipeId: $routeParams.recipeId
});
};
// Create a new controller method for updating a single recipe
$scope.update = function() {
// Use the recipe '$update' method to send an appropriate PUT request
$scope.recipe.$update(function() {
// If an recipe was updated successfully, redirect the user to the recipe's page
$location.path('recipes/' + $scope.recipe._id);
}, function(errorResponse) {
// Otherwise, present the user with the error message
$scope.error = errorResponse.data.message;
});
};
// Create a new controller method for deleting a single recipe
$scope.delete = function(recipe) {
// If an recipe was sent to the method, delete it
if (recipe) {
// Use the recipe '$remove' method to delete the recipe
recipe.$remove(function() {
// Remove the recipe from the recipes list
for (var i in $scope.recipes) {
if ($scope.recipes[i] === recipe) {
$scope.recipes.splice(i, 1);
}
}
});
} else {
// Otherwise, use the recipe '$remove' method to delete the recipe
$scope.recipe.$remove(function() {
$location.path('recipes');
});
}
};
}
]);
这是表格
<section data-ng-controller="RecipesController">
<div class="full-width-container">
<div class="create-recipe">
<div class="content">
<form data-ng-submit="create()" novalidate>
<h1>Create A New Recipe</h1>
<label>Title</label>
<div>
<input type="text" data-ng-model="title" placeholder="Title" id="title" required />
</div>
<label>Main Image</label>
<div>
<input type="text" data-ng-model="mainImage" placeholder="Enter image url" id="mainImage" />
</div>
<label>Recipe</label>
<div>
<textarea data-ng-model="content" placeholder="Enter Recipe" id="content"></textarea>
</div>
<label>Category</label>
<div>
<input type="text" data-ng-model="category" placeholder="Available categories (Breakfast, Brunch, Lunch, Dinner)" id="category"/>
</div>
<label>Tags</label>
<div>
<input type="text" data-ng-model="tags" placeholder="Seperate tags by a comma" id="tags"/>
</div>
<div>
<input type="submit" value="Create" class="form-submit" />
</div>
<div data-ng-show="error">
<strong data-ng-bind="error"></strong>
</div>
</form>
</div>
</div>
</div>
</section>
感谢您的建议,mcpDESIGNS。我尝试了你的建议,但仍然没有运气。当我提交它时,它像以前一样成功完成,但是当我查看数据库时,除了id,author和date之外,它仍然是空的。我不知道我是否正确实施了您的建议。
第一个建议 -
<section ng-controller="RecipesController">
<div class="full-width-container">
<div class="create-recipe">
<div class="content">
<form ng-submit="create(recipe)" novalidate>
<h1>Create A New Recipe</h1>
<label>Title</label>
<div>
<input type="text" ng-model"recipe.title" placeholder="Title" id="title" required />
</div>
<label>Main Image</label>
<div>
<input type="text" ng-model"recipe.mainImage" placeholder="Enter image url" id="mainImage" />
</div>
<label>Recipe</label>
<div>
<textarea ng-model"recipe.content" placeholder="Enter Recipe" id="content"></textarea>
</div>
<label>Category</label>
<div>
<input type="text" ng-model"recipe.category" placeholder="Available categories (Breakfast, Brunch, Lunch, Dinner)" id="category"/>
</div>
<label>Tags</label>
<div>
<input type="text" ng-model"recipe.tags" placeholder="Seperate tags by a comma" id="tags"/>
</div>
<div>
<input type="submit" value="Create" class="form-submit" />
</div>
<div ng-show="error">
<strong ng-bind="error"></strong>
</div>
</form>
</div>
</div>
</div>
</section>
第二个建议 -
// Invoke 'strict' JavaScript mode
'use strict';
// Create the 'recipes' controller
angular.module('recipes').controller('RecipesController', ['$scope', '$routeParams', '$location', 'Authentication', 'Recipe',
function($scope, $routeParams, $location, Authentication, Recipe) {
// Expose the Authentication service
$scope.authentication = Authentication;
// Create a new controller method for creating new recipes
$scope.create = function() {
// Use the form fields to create a new recipe $resource object
var recipe = new Recipe({
title: $scope.title,
mainImage: $scope.mainImage,
content: $scope.content,
category: $scope.category,
tags: $scope.tags
});
// Use the recipe '$save' method to send an appropriate POST request
recipe.$save(function(response) {
// If an recipe was created successfully, redirect the user to the recipe's page
$location.path('recipes/' + response._id);
}, function(errorResponse) {
// Otherwise, present the user with the error message
$scope.error = errorResponse.data.message;
});
};
// Create a new controller method for retrieving a list of recipes
$scope.find = function() {
// Use the recipe 'query' method to send an appropriate GET request
$scope.recipes = Recipe.query();
};
// Create a new controller method for retrieving a single recipe
$scope.findOne = function() {
// Use the recipe 'get' method to send an appropriate GET request
$scope.recipe = Recipe.get({
recipeId: $routeParams.recipeId
});
};
// Create a new controller method for updating a single recipe
$scope.update = function() {
// Use the recipe '$update' method to send an appropriate PUT request
$scope.recipe.$update(function() {
// If an recipe was updated successfully, redirect the user to the recipe's page
$location.path('recipes/' + $scope.recipe._id);
}, function(errorResponse) {
// Otherwise, present the user with the error message
$scope.error = errorResponse.data.message;
});
};
// Create a new controller method for deleting a single recipe
$scope.delete = function(recipe) {
// If an recipe was sent to the method, delete it
if (recipe) {
// Use the recipe '$remove' method to delete the recipe
recipe.$remove(function() {
// Remove the recipe from the recipes list
for (var i in $scope.recipes) {
if ($scope.recipes[i] === recipe) {
$scope.recipes.splice(i, 1);
}
}
});
} else {
// Otherwise, use the recipe '$remove' method to delete the recipe
$scope.recipe.$remove(function() {
$location.path('recipes');
});
}
};
}
]);
这是我的recipes.server.routes.js
var users = require('../../app/controllers/users.server.controller'),
recipes = require('../../app/controllers/recipes.server.controller');
var needsRole = function(role) {
return function(req, res, next) {
if (req.user && req.user.role === role)
next();
else
res.status(401, 'Unauthorized');
};
};
// Deine the routes 'module' method
module.exports = function(app) {
// Setting the 'recipes' base routes
app.route('/api/recipes')
.get(recipes.list)
.post(users.requiresLogin, needsRole("admin"), recipes.create);
// Set up the 'recipes' parameterized routes
app.route('/api/recipes/:recipeId')
.get(recipes.read)
.put(users.requiresLogin, recipes.hasAuthorization, recipes.update)
.delete(users.requiresLogin, recipes.hasAuthorization, recipes.delete);
// Set up the 'recipeId' parameter middleware
app.param('recipeId', recipes.recipeByID);
};
答案 0 :(得分:1)
所以从我所看到的,问题出在你的$scope.create
函数中。
在您的功能中,您要创建要发送到数据库的对象,但最大的问题是:this.
由于您在那里创建资源,{{1可能指的是完全不同的东西,而不是你的this
。
您有2个选项,要么全部更改为:
$scope
或者:
尝试在整个表单的视图中创建title : $scope.title,
mainImage : $scope.mainImage,
// etc
。例如:
object
这样您就可以将整个对象传递给<input ng-model="recipe.title" />
<input ng-model="reciple.mainImage" />
// etc
ng-submit
。
当您进入控制器时,您可以使用create(recipe)
访问该对象的每个属性,这样更容易。您甚至可以将整个事情传递给您的资源并让它自己映射。例如recipe.
。