繁体   English   中英

AngularJS表单不提交数据

[英]Angularjs form not submitting data

我正在创建一个MEAN堆栈应用程序,并且一直在使用Amos Q. Haviv撰写的《 Mean Web Development》一书来帮助我。 我遇到了一个问题,该表单应该提交配方,但是当我检查数据库时,该条目中有一个id,日期和作者,但没有标题,mainImage,内容,类别或标签。 在过去的几天中,我一直在尝试自己解决问题,并再次阅读本书以查看是否犯了任何错误,但是没有运气。

这是我的模型:

// 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');
                });
            }
        };
    }
]);

这是我的配方.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);
};

因此,据我$scope.create ,问题出在您的$scope.create函数中。

在函数中,您正在创建要发送到数据库的对象,但是最大的问题是: this. 由于您是在此处创建资源,因此this可能是指完全不同的东西,而不是$scope

您有2个选项,可以将它们全部更改为:

title : $scope.title,
mainImage : $scope.mainImage, 
// etc

要么:

尝试在整个表单的视图中简单地创建一个object 例如:

<input ng-model="recipe.title" />
<input ng-model="reciple.mainImage" />
// etc

这样,您可以将整个对象传递给ng-submit create(recipe)

当您在控制器中时,可以使用recipe.访问该对象的每个属性recipe. ,容易得多。 您甚至可以将整个内容传递给您的资源,并对其进行映射。 new Recipe(recipe); 例如。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM