将数据从Node / Mongoose发送到Backbone;只接收JSON对象

时间:2016-03-13 22:08:18

标签: node.js mongodb express backbone.js mongoose

我是Node的新手,对Backbone来说还是新手,所以我确定我的问题非常基本 - 请耐心等待我!

我尝试从Node路由功能返回数据,然后使用Backbone将其拾取并在我的视图中呈现它。发生了什么是Node将我的JSON对象发送回页面,而不是使用我的视图呈现它。

我关注生成this tutorialthis code,我知道我的代码不是最漂亮的,但我不明白使Blogroll应用程序工作的原因是什么什么阻止了我的工作!

非常感谢任何见解!

以下是代码:

在app.js中:

app.get('/add', recipeController.getAddRecipe);
app.post('/add', recipeController.postIngredient);
app.delete('/add:id', recipeController.deleteIngredient);
app.put('/add:id', recipeController.putIngredient);

在controllers / recipe.js中:

exports.getAddRecipe = function(req, res) {
  console.log("getAddRecipe route entered");
  Ingredient.find(function(err, docs) {
    docs.forEach(function(item) {
      console.log("Received a GET request for _id: " + item._id);
    })
    console.log("Sending docs");
    res.send(docs);
  });
};

在public / js / backbone-models.js中:

$(document).ready(function() {
    Backbone.Model.prototype.idAttribute = '_id';

    // Backbone Model
    var Ingredient = Backbone.Model.extend({
        defaults: {
            qty: '',
            item: '',
            unit: '',
            prep: ''
        }
    });

    // Backbone Collection
    var Ingredients = Backbone.Collection.extend({
        url: 'http://localhost:3000/add'
    })

    // instantiate a Collection
    console.log("Creating 'ingredients'...");
    var ingredients = new Ingredients();

    // Backbone View for one ingredient
    var IngredientView = Backbone.View.extend({
        model: new Ingredient(),
        tagName: 'div',
        template: _.template($('.ingredients-list-template'),
        initialize: function() {
            this.template = _.template($('.ingredients-list-template').html());
        },
        events: {
            'dblclick .ingredient.card': 'edit',
            'enter .ingredient.card': 'update', // ingredient.card, *OR* input ?? TO DO
            'escape .ingredient.card': 'cancel', // ingredient.card, *OR* input ?? TO DO
            'click .delete-ingredient': 'delete'
        },
        edit: function() {
            var qty = this.$('.qty').html();
            var item = this.$('.item').html();
            var unit = this.$('.unit').html();
            var prep = this.$('.prep').html();

            this.$('qty').html("<input type='text' class='qty-update' value='" + qty + "'>");
            this.$('item').html("<input type='text' class='item-update' value='" + item + "'>");
            this.$('unit').html("<input type='text' class='unit-update' value='" + unit + "'>");
            this.$('prep').html("<input type='text' class='prep-update' value='" + prep + "'>");
        },
        update: function() {
            this.model.set('qty', $('.qty-update').val());
            this.model.set('item', $('.item-update').val());
            this.model.set('unit', $('.unit-update').val());
            this.model.set('prep', $('.prep-update').val());

            this.model.save(null, {
                success: function(response) {
                    console.log('Successfully UPDATED ingredient with _id: ' + response.toJSON()._id);
                },
                error: function(err) {
                    console.log('Failed to update ingredient!');
                }
            });
        },
        cancel: function() {
            ingredientsView.render();
        },
        delete: function() {
            this.model.destroy({
                success: function(response) {
                    console.log('Successfully DELETED ingredient with _id: ' + response.toJSON()._id);
                },
                error: function(err) {
                    console.log('Failed to delete ingredient!');
                }
            });
        },
        render: function() {
            this.$el.html(this.template(this.model.toJSON()));
            return this;
        }
    });

    // Backbone View for all ingredients
    var IngredientsView = Backbone.View.extend({
        model: ingredients,
        el: $('.ingredients-inner'),
        initialize: function() {
            var self = this;
            this.model.on('add', this.render, this);
            this.model.on('change', function() {
                setTimeout(function() {
                    self.render();
                }, 30);
            }, this);
            this.model.on('remove', this.render, this);

            this.model.fetch({
                success: function(response) {
                    _.each(response.toJSON(), function(item) {
                        console.log('Successfully GOT ingredient with _id: ' + item._id);
                    })
                },
                error: function() {
                    console.log('Failed to get ingredients!');
                }
            });
        },
        render: function() {
            var self = this;
            this.$el.html('');
            _.each(this.model.toArray(), function(ingredient) {
                self.$el.append((new IngredientView({model: ingredient})).render().$el);
            });
            return this;
        }
    });

    console.log("Creating 'ingredientsView'...");
    var ingredientsView = new IngredientsView();


    console.log("Document ready...");
    $('.add-ingredient').on('click', function() {
        var ingredient = new Ingredient({
            qty: $('.qty-input').val(),
            item: $('.item-input').val(),
            unit: $('.unit-input').val(),
            prep: $('.prep-input').val()
        });
        $('.qty-input').val('');
        $('.item-input').val('');
        $('.unit-input').val('');
        $('.prep-input').val('');
        ingredients.add(ingredient);
        ingredient.save(null, {
            success: function(response) {
                console.log('Successfully SAVED ingredient with _id: ' + response.toJSON()._id);
            },
            error: function() {
                console.log('Failed to save ingredient!');
            }
        })
    });
});

来自views / recipes / add.jade:

extends ../layout

block content
  script(type="text/javascript" src="/js/add.js")
  .page
    .ingredients-pane
      .ingredients-inner.column
      // ingredients form
      .card.ingredient-form
        form#ingredientForm
          .input-field
            input(type='text' class="qty-input" name='qty' id="qty" placeholder="Quantity (e.g. 200)")
          .input-field
            input(type='number' class="item-input" name='qty' id="item" placeholder="Item (e.g. onions)")
          .input-field
            input(type='text' class="unit-input" name='unit' id="unit" placeholder="Unit (e.g. grams)")
          .input-field
            input(type='text' class="prep-input" name='prep' id="prep" placeholder="Prep (e.g. chopped)")

          button(type="button" class="add-ingredient" id="ingredientButton").btn.waves-effect.waves-light Add ingredient

    script(type="text/template" id="ingredients-list-template").
      <div class="ingredient card">
        <span class="qty"><%= qty %></span>
        <span class="item"><%= item %></span>
        <span class="unit"><%= unit %></span>
        <span class="prep"><%= prep %></span>
      </div>

1 个答案:

答案 0 :(得分:0)

所以,我想出来了,这是一个荒谬的愚蠢的事情;这是一个路由问题。

我以为我可以在/ {添加res.send(myJSONData)res.render('myAddView')。我没有意识到的是我需要两者 - 首先是render我的添加视图,然后是send JSON数据本身 - 到不同的路径,即/ api / myThing。

所以我最终得到了(如果其他人遇到同样的问题):

在app.js中:

app.get('/add', recipeController.addRecipe);

app.get('/api/ingredients', recipeController.getIngredients);
app.post('/api/ingredients', recipeController.postIngredient);
app.delete('/api/ingredients:id', recipeController.deleteIngredient);
app.put('/api/ingredients:id', recipeController.putIngredient);

在controllers / recipe.js中:

exports.addRecipe = function(req, res) {
  res.render('recipes/add', {
    title : 'Add a new recipe'
  });
};

exports.getIngredients = function(req, res) {
  console.log("getAddRecipe route entered");
  Ingredient.find(function(err, docs) {
    docs.forEach(function(item) {
      console.log("Received a GET request for _id: " + item._id);
    })
    res.send(docs);
  });
};

exports.postIngredient = function(req, res) {
  console.log('Received a POST request:')
  for (var key in req.body) {
    console.log(key + ': ' + req.body[key]);
  }
  var ingredient = new Ingredient(req.body);
  ingredient.save(function(err, doc) {
    res.send(doc);
  });
};

exports.deleteIngredient = function(req, res) {
  console.log('Received a DELETE request for _id: ' + req.params.id);
  Ingredient.remove({_id: req.params.id}, function(err, doc) {
    res.send({_id: req.params.id});
  });
}

exports.putIngredient = function(req, res) {
  console.log('Received an UPDATE request for _id: ' + req.params.id);
  Ingredient.update({_id: req.params.id}, req.body, function(err) {
    res.send({_id: req.params.id});
  });
}

在我的Backbone文件中,告诉Backbone在哪里可以找到所需的JSON数据:

// Backbone Collection
var Ingredients = Backbone.Collection.extend({
    url: '/api/ingredients'
})