Backbone.listenTo vs this.listenTo

2019-08-10 12:24发布

Inside a Backbone object (model,view,router), we can call this.listenTo

like so

var BodyView = Backbone.View.extend({
  initialize: function() {
    this.listenTo(Backbone, 'prevent-scroll', this.preventScroll);
  },

  preventScroll: function(prevent) {
    // .prevent-scroll has the following CSS rule: overflow: hidden;
    this.$el.toggleClass('prevent-scroll', prevent);
  }
});

// And now from anywhere in the code:
Backbone.trigger('prevent-scroll', true); // prevent scrolling

however, is there a way to use

Backbone.listenTo, instead of this.listenTo? I don't see any examples of this online, but I don't see why it shouldn't exist.

Also, one more question in the call

Backbone.trigger('prevent-scroll', true);

where is the true argument being passed to? I don't get it

3条回答
Animai°情兽
2楼-- · 2019-08-10 13:11

In Javascript this is a special keyword, it holds the object that you're currently working with so to speak.

For example,

$("button").on("click",function(event){
console.log($(this));
})

This would log out to the console all the properties of the button you clicked.

I would also have a look into callbacks.

查看更多
欢心
3楼-- · 2019-08-10 13:12

You didn't explain what you need it for, it makes no sense to use listenTo outside the context of a particular collect/view/model instance. The whole point of listenTo is so one object can listen to another (from inside itself) and perform cleanup on the destruction of that object, as well as bind the context to this.

e.g. in a View this.listenTo(this.model, ..) is better than this.model.on(...) because when the view is destroyed the listener will be removed.

If you are outside of that context you just use the .on method, which does the same thing.

var someModel = new Backbone.Model();
someModel.on('change:text', function(model, newValue) { ... }

If you wish to share a model you can either pass it down through views (if you have set up views to have a hierarchy). Or like with your other template question you are better off setting up your app to use RequireJS. Then you can have a global AppState model for instance that would look something like this:

define([
    'backbone'
], function(Backbone) {

    var AppState = Backbone.Model.extend({

        ...

    });

    // Return as a singleton (instantiated).
    return new AppState();
});

That way every other component could require it in and since it is a singleton they all have access to the same model and can listen to events on it.

查看更多
叛逆
4楼-- · 2019-08-10 13:17

I was looking at the annotated Backbone source. http://backbonejs.org/docs/backbone.html#section-19

There is a clear way to do this. The naive standpoint is that you should be able to pass around messages on the front-end wherever Backbone is, not just wherever Backbone.Views, Backbone.Models, etc, are.

If you put this on your front-end, it will work:

    Backbone.Events.on('event1',function(msg){
        alert(msg);
     });

    Backbone.Events.trigger('event1','hiiii');

Not only that, you can also simply do:

    Backbone.on('event1',function(msg){
            alert(msg);
     });

    Backbone.trigger('event1','hiiii');

this is because of this call in the Backbone source:

_.extend(Backbone, Events);

Backbone.Events is:

a module that can be mixed in to any object in order to provide it with custom events. You may bind with on or remove with off callback functions to an event; trigger-ing an event fires all callbacks in succession.

for example:

    var object = {};
    _.extend(object, Backbone.Events);
    object.on('expand', function(){ alert('expanded'); });
    object.trigger('expand');
查看更多
登录 后发表回答