Получение «типа» модели представления

вы можете получить доступ к модели View из методов View - например, render() (через его свойство model). Но допустим, у вас есть много разных моделей и вы используете их с одним и тем же типом представления, изменяя свойство представления model, когда вам нужно.

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

var Model1 = Backbone.Model.extend();
var Model2 = Backbone.Model.extend();

var MyView = Backbone.View.extend({
  render:function(){
    console.log(" you're using: "+ model); // how to determine here is it using Model1 or Model2
  }
})

var mv1 = new MyView({model: new Model1()})
var mv2 = new MyView({model: new Model2()})

person iLemming    schedule 26.10.2012    source источник
comment
Поможет ли это? (Я предполагаю, что вы ищете что-то вроде typeof...) jsbin.com/emeyay/1/edit   -  person DashK    schedule 27.10.2012
comment
@Dashk да ... пожалуйста, напишите это как ответ   -  person iLemming    schedule 27.10.2012


Ответы (2)


Сохраняя это просто...

var Model1 = Backbone.Model.extend();
var Model2 = Backbone.Model.extend();

var MyView = Backbone.View.extend({
  render:function(){
    if (this.model instanceof Model1) {
      alert("You're using model1");
    }
    else if (this.model instanceof Model2) {
      alert("You're using model2");
    }
    else {
      alert("I've no idea what you're using");
    }
  }
})

var mv1 = new MyView({model: new Model1()});
var mv2 = new MyView({model: new Model2()});
mv1.render();
mv2.render();
person DashK    schedule 27.10.2012
comment
Ключевое слово здесь много. С множеством различных моделей этот простой подход становится непрактичным. Потому что вам нужно не только добавлять ветвь для каждого нового типа модели, но и располагать их в правильном порядке, чтобы подклассы всегда предшествовали суперклассам. - person PointedEars; 27.10.2012

У объектов есть идентификатор, а не имя. Если вы хотите узнать имя конструктора, создавшего объект (которое можно считать типом объекта, см. Спецификация ECMAScript), пуленепробиваемый подход состоит в том, чтобы сделать эту информацию частью сконструированного объекта:

var Model1 = Backbone.Model.extend({type: "Model1"});
var Model2 = Backbone.Model.extend({type: "Model2"});

var MyView = Backbone.View.extend({
  render: function () {
    console.log("You are using " + this.model.type);
  }
});

var mv1 = new MyView({model: new Model1()});
var mv2 = new MyView({model: new Model2()});

Таким образом, объекты модели наследуют свойство type через цепочку прототипов. См. также http://backbonejs.org/#View-render.

Альтернативные, менее эффективные и менее надежные решения включают:

  • Присвоение конструктору имени и доступ к нему:

    var Model1 = Backbone.Model.extend();
    Model1.name = "Model1";
    
    var MyView = Backbone.View.extend({
      render: function () {
        console.log("You are using " + this.model.constructor.name);
      }
    });
    
    var mv1 = new MyView({model: new Model1()});
    var mv2 = new MyView({model: new Model2()});
    

    (Дополнительное присвоение свойству name не требовалось, если конструктор был

    var Model1 = function Model1 () {
      // …
    };
    

    or

    function Model1 ()
    {
      // … 
    }
    

    но это, к сожалению, не для Backbone.js.)

  • Разбор строкового представления именованного экземпляра Function, такого как конструктор. Но это зависит от реализации:

    var Model1 = function Model1 () {
      // …
    };
    
    var MyView = Backbone.View.extend({
      getModelName: function () {
        var aFunction = this.model.constructor;
        return (aFunction != null && typeof aFunction.name != "undefined" && aFunction.name)
          || (String(aFunction).match(/\s*function\s+([A-Za-z_]\w*)/) || [, ""])[1];
      },
    
      render: function () {
        console.log("You are using " + this.getModelName());
      }
    });
    

    (Реализовано как jsx.object.getFunctionName(). , Но опять же, AIUI не полностью возможен с Backbone.js.)

  • Используя instanceof, как предложено в ответе DashK. Но это не дает вам информацию немедленно или надежно. Потому что вы должны сначала поставить наиболее значимое имя в цепочке прототипов и изменить метод всякий раз, когда вы меняете цепочку прототипов, иначе вы получите ложные срабатывания и ложные отрицания:

    var MyView = Backbone.View.extend({
      render: function () {
        var modelName = "an unknown model";
    
        if (this.model instanceof Model1)
        {
          modelName = "Model1";
        }
        else if (this.model instanceof Model2)
        {
          modelName = "Model2";
        }
        else if (this.model instanceof Supermodel)
        {
          modelName = "Supermodel";
        }
    
        console.log("You are using " + modelName);
      }
    });
    
person PointedEars    schedule 26.10.2012