Подтвердить что ты не робот

Пользовательский конструктор Backbone.js?

Я ищу несколько примеров для создания пользовательского конструктора на своих моделях. Я хочу, чтобы структура модели/данных была по-разному, а затем просто устанавливала ее как атрибуты.

Может кто-нибудь показать мне некоторый базовый пример того, как это сделать?

Спасибо!

4b9b3361

Ответ 1

Если вы действительно хотите переопределить конструктор, передайте свойство constructor в Backbone.Model.extend(), например:

var Klass = Backbone.Model.extend( {

  constructor : function ( attributes, options ) {

    // ...

  }

} );

Если вы хотите вызвать встроенный конструктор из своего настраиваемого конструктора, вы можете сделать что-то вроде:

var Klass = Backbone.Model.extend( {

  constructor : function ( attributes, options ) {

    Backbone.Model.apply( this, arguments );

  }

} );

Или, если вы не хотите повторять имя переменной, содержащей родительский класс, по всему подклассу, или вы не хотите беспокоиться о значении этой переменной, вы можете сделать что-то вроде следующее:

var Klass;

var parent_klass = Backbone.Model.prototype;

( function ( parent_klass ) {

  Klass = parent_klass.constructor.extend( {

    constructor : function ( attributes, options ) {

      parent_klass.constructor.apply( this, arguments );

    }

  } );

} )( parent_klass );

Или, если вы предпочитаете способ @Claude предлагает, но повторяя имя переменной подкласс в подклассе вместо родительского класса var name:

var Klass = Backbone.Model.extend(

  {

    constructor : function ( attributes, options ) {

      Klass.parent_klass.constructor.apply( this, arguments );

    }

  },

  {

    parent_klass : Backbone.Model.prototype

  }

);

Если вы хотите больше советов, чем это, вы должны быть более конкретными о том, чего вы хотите достичь.

Все, что вы хотите сделать только после встроенных функций конструктора, вероятно, вы должны сделать в initialize().

Ответ 2

Вот как я переопределяю конструктор Backbone.Model по умолчанию:

Backbone.Model = (function(Model) {
  // Define the new constructor
  Backbone.Model = function(attributes, options) {
    // Your constructor logic here
    // ...
    // Call the default constructor if you wish
    Model.apply(this, arguments);
    // Add some callbacks
    this.on('event', this.myCallback, this);
  };
  // Clone static properties
  _.extend(Backbone.Model, Model);      
  // Clone prototype
  Backbone.Model.prototype = (function(Prototype) {
    Prototype.prototype = Model.prototype;
    return new Prototype;
  })(function() {});
  // Update constructor in prototype
  Backbone.Model.prototype.constructor = Backbone.Model;
  return Backbone.Model;
})(Backbone.Model);

После этого вы должны убедиться, что прототип Backbone.Collection использует обновленный конструктор Backbone.Model:

_.extend(Backbone.Collection.prototype, {
  model: Backbone.Model
});

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

Ответ 3

Как я упоминал в комментарии, будьте осторожны при использовании this.constructor.__super__ (или this.__super__), чтобы вы не оказались в бесконечном цикле (Maximum call stack size exceeded в Chrome).

Попробуйте следующее в консоли (на свой страх и риск, это приведет к вышеупомянутой бесконечной петле)

var A = Backbone.Model.extend({constructor: function () {
  console.log("log: A");
  this.constructor.__super__.constructor.apply(this, arguments);
}});

var B = A.extend({constructor: function () {
  console.log("log: B");
  this.constructor.__super__.constructor.apply(this, arguments);
}});

new A();
//  log: A
//  > Backbone.model.extend.constructor
new B();
//  log: B
//  (8192) log: A
//  > RangeError: Maximum call stack size exceeded

Причина в том, что при создании B, this в конструкторе для A указывает на экземпляр B, поэтому this.constructor.__super__.constructor продолжает указывать на конструктор A, который называется временем и время снова.

Если вы хотите "предполагаемое поведение", используйте один из следующих синтаксисов:

var A = Backbone.Model.extend({constructor: function () {
  console.log("log: A");
  A.__super__.constructor.apply(this, arguments);
}});

var B = A.extend({constructor: function () {
  console.log("log: B");
  B.__super__.constructor.apply(this, arguments);
}});

new A();
//  log: A
//  > Backbone.model.extend.constructor
new B();
//  log: B
//  log: A
//  > A.extend.constructor

или непосредственно без __super__:

var A = Backbone.Model.extend({constructor: function () {
  console.log("log: A");
  Backbone.Model.apply(this, arguments);
}});

var B = A.extend({constructor: function () {
  console.log("log: B");
  A.apply(this, arguments);
}});

new A();
//  log: A
//  > Backbone.model.extend.constructor
new B();
//  log: B
//  log: A
//  > A.extend.constructor

Ответ 4

Если вы хотите написать свою модель самостоятельно, выполните следующие действия:

var YourModel = function () {
    // your constructor here
};

_.extend(YourModel.prototype, Backbone.Model.prototype, {
    // your model method here
});

Будьте осторожны, я думаю, вам нужно проконсультироваться с Backbone.Model конструктором исходным кодом. Но я думаю, что это не очень хорошая идея. Метод Override initialize - правильный путь:

var YourModel = Backbone.Model.extend({
    initialize: function (attrs, options) {
        Backbone.Model.prototype.initialize.apply(this, arguments); // call super constructor

        // your constructor code here
    }
});

Ответ 5

Похоже, вы ищете метод initialize. Он вызывал, когда вы создаете новую модель, и можете использовать ее для того, что вам нужно:

var myModel = Backbone.Model.extend({
  initialize: function() {
    // do something besides setting attributes or model
    alert('myModel is ready for action!');
  }
});

new myModel();

Если вы хотите сделать что-то более активное, вы можете переопределить метод constructor в ядре Backbone. Тем не менее, это намного сложнее. Гораздо лучше работать с открытыми методами, если вы можете!

Ответ 6

Что-то нужно знать при переопределении конструктора Backbone.Model - если вы не вызываете Backbone.Model.apply, тогда Model.cid может не быть установлен.

Это плохо. Если cid не задан в нескольких моделях, коллекция может считать это дубликат первой модели в вашей коллекции и не позволит ее добавлять.