Backbone.xmpp: различать типы элементов на основе идентификатора элемента.

Я хочу различать элементы узлов на основе item_id с помощью Backbone.xmpp. Например, в todo.app для каждого элемента "todo", который я хочу чтобы иметь возможность назначать разные заметки (или несколько пользователей публикуют заметки по каждому «делу»). Я подумал о назначении этих заметок задаче на основе идентификатора задачи.

Могу ли я использовать реляционный Backbone с Backbone.xmpp?

Любая помощь или рекомендации приветствуются.

Edit2: Какие параметры у меня есть для хранения вложенных моделей в листовых узлах на сервере xmpp?

  1. задачи и заметки — это отдельные элементы, публикуемые на конечном узле. Будет ли эффективно назначать комментарии к задачам? Различие будет основано на идентификаторах элементов (todoid: todo_1, noteid: todo

    $(function(){
    
    // ------------------- Todo Model ------------------
    
    var Todo = Backbone.RelationalModel.extend({
    
      relations: [{
         type: Backbone.HasMany,
         key: "children",
         relatedModel: "Todo",
         collectionType: "TodoList",
         reverseRelation: {
             key: "parent",
             includeInJSON: "id"
         } 
      }],
    
    initialize: function() {
      console.log("MODEL: initialize()");
      if (!this.get("order") && this.get ("parent")) {
        this.set( {order: this.get("parent").nextChildIndex() });
      }
    },
    
    defaults: function() {
        console.log("MODEL: defaults()");
      return { 
          done: false,
          content: "default content" };
    },
    
    nextChildIndex: function() {
        var children = this.get( 'children' );
        return children && children.length || 0;
    },
    
    clear: function() {
      this.destroy();
    }
    });
    
    note_1).

  2. todos — это элементы, а заметки — это массив объектов внутри элемента todo (объекты JSON)? Но с этим решением я не буду получать уведомления при публикации заметок, так как это будет обновление элемента списка задач. Кроме того, все заметки будут храниться в одном элементе — и это может занять очень много времени.

  3. Первоначально у меня была идея отображать задачи на конечных узлах (как имя конечного узла или атрибут «заголовок») и примечания к элементам, но BB.xmpp пока не поддерживает это, верно?

Поэтому я склоняюсь к первому решению, в котором задачи и заметки различаются по идентификатору элемента.

Как это возможно в Backbone.xmpp?

Edit1: код предназначен для оригинального todo.app с локальным хранилищем.

$(function(){

// ------------------- Todo Model ------------------

var Todo = Backbone.RelationalModel.extend({

  relations: [{
     type: Backbone.HasMany,
     key: "children",
     relatedModel: "Todo",
     collectionType: "TodoList",
     reverseRelation: {
         key: "parent",
         includeInJSON: "id"
     } 
  }],

initialize: function() {
  console.log("MODEL: initialize()");
  if (!this.get("order") && this.get ("parent")) {
    this.set( {order: this.get("parent").nextChildIndex() });
  }
},

defaults: function() {
    console.log("MODEL: defaults()");
  return { 
      done: false,
      content: "default content" };
},

nextChildIndex: function() {
    var children = this.get( 'children' );
    return children && children.length || 0;
},

clear: function() {
  this.destroy();
}
});

// ------------------- Коллекция дел ------------------

var TodoList = Backbone.Collection.extend({
model: Todo,
// Save all of the todo items under the `"todos"` namespace.
localStorage: new Store("todos-backbone"),

done: function() {
  return this.filter(function(todo){ return todo.get('done'); });
},

});
var Todos = new TodoList;

// ------------------- Просмотр задач ------------------

var TodoView = Backbone.View.extend({
tagName:  "li",

template: _.template($('#item-template').html()),

events: {
  "keypress input.add-child": "addChild",
  "click .check"              : "toggleDone",
  "dblclick label.todo-content" : "edit",
  "click span.todo-destroy"   : "clear",
  "keypress .todo-input"      : "updateOnEnter",
  "blur .todo-input"          : "close"
},

initialize: function() {
    console.log("TODOVIEW: initialize()");
  this.model.bind('change', this.render);
  this.model.bind('destroy', this.remove);

  this.model.bind("update:children", this.renderChild);
  this.model.bind("add:children", this.renderChild);

  this.el = $( this.el );
  this.childViews = {};
},

render: function() {
  console.log("TODOVIEW: render()");
  $(this.el).html(this.template(this.model.toJSON()));
  this.setText();
  this.input = this.$('.todo-input');

  this.el.append("<ul>", {"class": "children"}).append("<input>", { type: "text", "class": "add-child" });

  _.each(this.get("children"), function(child) {
      this.renderChild(child);
  }, this);      
    return this;
},

  addChild: function(text) {
      console.log("TODOVIEW: addChild()");
      if (e.keyCode == 13){
          var text = this.el.find("input.add-child").text();
          var child = new Todo( { parent: this.model, text: text});
      }
  },

  renderChild: function(model){
      console.log("TODOVIEW: renderChild()");
    var childView = new TodoView({ model: model});
    this.childViews[model.cid] = childView;
    this.el.find("ul.children").append(childView.render());
  },

// Remove the item, destroy the model.
clear: function() {
    console.log("TODOVIEW: clear()");
  this.model.set({parent: null});
  this.model.destroy();
  //this.model.clear();
}
});

// ------------------ Приложение ------------------------

var AppView = Backbone.View.extend({
el: $("#todoapp"),

statsTemplate: _.template($('#stats-template').html()),

events: {
  "keypress #new-todo":  "createOnEnter",
  "keyup #new-todo":     "showTooltip",
  "click .todo-clear a": "clearCompleted",
  "click .mark-all-done": "toggleAllComplete"
},

initialize: function() {
    console.log("APPVIEW: initialize()");
  _.bindAll(this, 'addOne', 'addAll', 'render', 'toggleAllComplete');

  this.input = this.$("#new-todo");

  Todos.bind('add',     this.addOne);
  Todos.bind('reset',   this.addAll);
  Todos.bind('all',     this.render);

  Todos.fetch();
},

render: function() {

},

addOne: function(todo) {
  var view = new TodoView({model: todo});
  this.$("#todo-list").append(view.render().el);
},

addAll: function() {
  Todos.each(this.addOne);
},

// Generate the attributes for a new Todo item.
newAttributes: function() {
  return {
    content: this.input.val(),
    order:   Todos.nextOrder(),
    done:    false
  };
},

createOnEnter: function(e) {
    console.log("APPVIEW: createOnEnter()");
  if (e.keyCode != 13) return;
  Todos.create( this.newAttributes());
  this.input.val('');
},
});
var App = new AppView;
});

person Community    schedule 02.07.2012    source источник


Ответы (1)


Нет ничего особенного, что мешало бы вам использовать Backbone.relational вместе с Backbone.xmpp, кроме как заставить его работать ;)

С другой стороны, Backbone.xmpp предоставляет уведомления в реальном времени, которые не будут активированы, если вы снова не сохраните модель задач, чтобы она была повторно опубликована на ваших узлах XMPP. Кроме того, XMPP (как и магистраль) поддерживает простое сдерживание, и вы просто работаете с ним, когда пытаетесь построить вокруг него реляционные данные.

Возможно, было бы намного проще просто предоставить примечания к элементам задач, что избавило бы вас от всех усилий, связанных с интеграцией с Backbone.relational.

person ggozad    schedule 03.07.2012
comment
Спасибо! Я действительно хочу, чтобы эти заметки были опубликованы. Речь идет лишь о более глубоком изучении backbone.xmpp и магистрали. Мне понадобится та же функциональность в моем приложении позже. Но по-прежнему не уверен, что следует использовать реляционные модели Backbone или вложенные модели, предложенные здесь: stackoverflow.com/questions/6353607/ . - person genericatz; 03.07.2012
comment
Не могли бы вы просмотреть код, который я написал до сих пор в файле Edit1. Он основан на оригинальном приложении todo, но я добавлю версию xmpp после того, как заставлю это работать. Я получаю Uncaught TypeError: Object function (obj) { return new wrapper (obj); } не имеет метода isObject для функции createOnEnter() представления приложения. Я просто хочу добавить заметки о todos. Здесь у модели Todo много дочерних задач (на основе модели todo). - person genericatz; 03.07.2012
comment
Немного сложно понять, что происходит, скрипка бы очень помогла! - person ggozad; 04.07.2012
comment
Хорошо, я понял, в чем мой главный вопрос, он в Edit 2. Завтра я создам Fiddle. - person genericatz; 07.07.2012
comment
Что вы подразумеваете под простым сдерживанием? Хранение заметок внутри элементов задач в массиве, например {todo1:{body: todo1, notes:[{id: todo1_note1,body: note1}], id:todo1 } ? Будет ли backbone.xmpp отправлять уведомления, когда я добавляю заметку в массив заметок? - person genericatz; 08.07.2012
comment
Да это верно. И действительно, backbone.xmpp уведомит, когда вы сохраните элемент списка дел с обновленными заметками. - person ggozad; 08.07.2012
comment
Эй! У меня есть реляционное приложение todo с комментариями к localStorage для работы. Но теперь я вижу другую проблему, если я использую массив внутри элемента узла для хранения заметок: если будет невероятно большое количество заметок, то запись в БД взорвется. Скажем, для приложения форума с сообщениями (элементами) и комментариями (массив внутри одного элемента). Может быть, другой подход будет лучше для сообщений и комментариев в виде элементов, опубликованных на листовом узле, но с разными структурами идентификаторов, чтобы различать их при выборке? Как бы я сопоставил этот подход с моделями и коллекциями? - person genericatz; 08.07.2012
comment
Openfire, который я сейчас использую для тестирования, использует тип TEXT для столбца полезной нагрузки (igniterealtime.org/builds/openfire/docs/latest/documentation/), поэтому после 64кб он будет обрезан и я не думаю, что во всех случаях будет достаточно для ветка и все комментарии к ветке. Я мог бы изменить тип столбца на LONGTEXT или MDIUMTEXT — как вы думаете, это будет работать нормально? - person genericatz; 08.07.2012