Модель не помещается в коллекцию backbonejs

jsfiddle

Я пытаюсь создать клиент сообщений, используя это руководство. в этот момент представление должно обновляться, когда новое сообщение вводится в поле и нажимается кнопка добавления. По какой-то причине событие «addMessage» не может добавить новую модель в коллекцию.

var messagesjson = [
  { 
    id: 3,
    message: "This is the message",
    sender: "gabriel",
    receiver: "gabriel",
    has_been_read: false,
    has_been_reported: false,
    created_at: "2014-10-23T19:55:20+0200",
    is_friend: false
  },
  {
    id: 5,
    message: "I'm loving this ",
    sender: "gabriel",
    receiver: "gabriel",
    has_been_read: true,
    has_been_reported: false,
    created_at: "2014-10-23T20:02:34+0200",
    is_friend: false
  }];

var MessageModel = Backbone.Model.extend({
  defaults:
  {
    id: 3,
    message: "This is the message",
    sender: "gabriel",
    receiver: "gabriel",
    has_been_read: false,
    has_been_reported: false,
    created_at: "2014-10-23T19:55:20+0200",
    is_friend: false
  }
});

var MessageView = Backbone.View.extend({
  tagName: "div",
  className: "listview",
  template: $('#messageTemplate').html(),
  render: function()
  {
    var tmpl = _.template(this.template);
    console.log(this.model);
    this.$el.html(tmpl(this.model.toJSON()));
    return this;
  }
});

var MessageCollection = Backbone.Collection.extend({
  model: MessageModel
});

var MessageCollectionView = Backbone.View.extend({
  el: $('#messages'),
  initialize: function()
  {
    this.collection = new MessageCollection(messagesjson);
    this.render();
    this.collection.on("add", this.renderMessage, this);
  },
  render: function()
  {
    var that = this;
    _.each(this.collection.models, function(item){
      that.renderMessage(item);
    },this);
  },
  events:{
    "click #add":"addMessage"
  },
  renderMessage: function(item)
  {
    var messageview = new MessageView({
      model: item
    });

    this.$el.append(messageview.render().el);
  },
  addMessage: function(e)
  {
    e.preventDefault();
    var formData = {};

    $("#addMessage").children("input").each(function (i, el) {
      formData[el.id] = $(el).val();
    });

    messagesjson.push(formData);
    this.collection.add(new MessageModel(formData));

    console.log(messagesjson);
  }
});

var messagecollectionview = new MessageCollectionView();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<div id="messages">  
  <form id="addMessage" action="#">
    <div>
      <label for="messageText">Message: </label>
      <input id="messageText" type="text" />
      <button id="add">Add</button>
    </div>
  </form>
</div>

<script type="text/template" id="messageTemplate">
  <a href="#" class="list autoWidth <% if(has_been_read) { %> selected <% } %>">
    <div class="list-content">
      <img src="//www.polyvore.com/cgi/img-thing?.out=jpg&size=l&tid=20774792" class="icon">
      <div class="data">
      <span class="item-title-secondary fg-gray"><b><%= sender %></b></span>
    </div>
    <span class="tertiary-text">
      <%= message %>
    </span>
    </div>
  </a>
</script>


person user3531149    schedule 28.10.2014    source источник
comment
Можете ли вы предоставить jsfiddle вашей проблемы?   -  person Mironor    schedule 28.10.2014
comment
только что добавил jsfiddle   -  person user3531149    schedule 28.10.2014


Ответы (1)


Вы устанавливаете идентификатор как 3 для всех новых моделей, поскольку ваш хэш по умолчанию содержит id: 3. Коллекция считает, что это та же самая модель, поскольку у нее уже есть модель с таким идентификатором.

Итак, сначала вам нужно изменить настройки по умолчанию с помощью id:null:

var MessageModel = Backbone.Model.extend({
    defaults:{
        id: null,
        message: "This is the message",
        sender: "gabriel",
        receiver: "gabriel",
        has_been_read: false,
        has_been_reported: false,
        created_at: "2014-10-23T19:55:20+0200",
        is_friend: false
    }
});

Затем вам нужно исправить код, получающий formData. Прежде всего, вы используете метод jQuery children(), который просматривает только непосредственные дочерние элементы. Это означает, что вы никогда не получите входные данные внутри формы, так как есть промежуточный div. Вы можете использовать find.

Во-вторых, вам нужно убедиться, что formData имеет свойство с именем message, чтобы оно могло переопределить значение по умолчанию message: "This is the message". Я бы добавил атрибут имени message к элементу ввода и использовал его как formData[el.name] = $(el).val();. (Позже вы можете использовать один из плагинов jquery serializeObject для автоматической сериализации всех входных элементов таким образом).

Таким образом, addMessage будет выглядеть так:

addMessage: function(e){
    e.preventDefault();
    var formData = {};

    $("#addMessage").find("input").each(function (i, el) {
        formData[el.name] = $(el).val();
    });                

    messagesjson.push(formData);
    this.collection.add(new MessageModel(formData));
}

Вы можете попробовать это в этой скрипте

person Daniel J.G.    schedule 28.10.2014
comment
Боже, ты лучший, я боролся с этим часами - person user3531149; 28.10.2014
comment
Рад, что смог помочь! :) - person Daniel J.G.; 28.10.2014