2015-08-21 4 views
1

Я создаю приложение стека MEAN, и я использовал книгу «Среднее развитие сети» Амосом К. Хавивом, чтобы помочь мне. Я столкнулся с проблемой, когда у меня есть форма, которая, как предполагается, отправляет рецепт, но когда я проверяю базу данных, запись там есть с идентификатором, датой и автором, но без заголовка, mainImage, контента, категории или тегов. Я пытался выяснить это самостоятельно в течение последних нескольких дней и снова перебирать книгу, чтобы увидеть, допустили ли я какие-либо ошибки, но не повезло.Форма Angularjs не отправляет данные

Вот моя модель:

// 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

Я хотел бы видеть ваши 'recipes.server.routes.js' и ваш сервис рецептов (на стороне клиента), также, когда вы говорите «нет заголовка, mainImage, контента, категории или тегов». Вы имеете в виду пробелы (значение по умолчанию для ваших обязательных полей), правильно? Если вы смотрите на запросы, отправляет сначала запрос OPTIONS, и если да, то как вы его обрабатываете? И вы подтвердили, что ваш req.body довольно пуст в create()? – ippi

+0

Вы действительно зарегистрировали теги и схемы комментариев? Console.log ошибка сразу после 'recipe.save (function (err) {console.log (err);})', чтобы посмотреть, что происходит –

+0

Иппи, да, когда я говорю пробелы, я имею в виду значение по умолчанию для моего требуемые поля. –

ответ

1

Так от того, что я могу видеть, проблема в вашей функции $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-submitcreate(recipe).

Когда вы находитесь в контроллере, вы можете получить доступ к каждому свойству этого объекта с помощью recipe., намного проще. Вы могли бы передать все это на свой ресурс и позволить ему отображать себя. new Recipe(recipe); например.

+0

Этот ответ неверен, $ scope.create - это функция, поэтому это относится к $ scope –

Смежные вопросы