How to hook async Backbone event to display of HTM

2019-07-09 04:25发布

What I am trying to do is make a call to the database and then display the result in some HTML. I have everything working (the data comes back from the database just fine), except I can't figure out to display the data.

I know that fetch() is async, but I'm not sure how to wire it into my collection view. Here is my Backbone:

    (function() {
        window.App = {
            Models: {},
            Collections: {},
            Views: {},
            Router: {}
        };

        window.template = function(id) {
            return _.template( $('#' + id).html() );
        };

        App.Models.Main = Backbone.Model.extend({
            defaults : {
                FName: ''
            }
        });

        App.Collections.Mains = Backbone.Collection.extend({
            model: App.Models.Main,
            initialize: function(mains) {
                this.fetch({success: function(main) {
                    $('#web-leads').html(main);
                }});
            },
            url: '../leads/main_contact'
        });

        App.Views.Mains = Backbone.View.extend({
            tagName: 'ul',
            render: function() {
                var ul = this.collection.each(this.addOne, this);
                return ul;
            },
            addOne: function(main) {
                var mainC = new App.Views.Main({ model: main});
                this.$el.append(mainC.render().el);
                return this;
            }
        });

        App.Views.Main = Backbone.View.extend({
            tagName: 'li',
            template: template('mainContactTemplate'),
            render: function () {
                this.$el.html(this.template(this.model.toJSON()));
                return this;
            }

        });

        main = new App.Views.Main();
        mains = new App.Collections.Mains(main);

    })();

What I need to be able to is call $('#web-leads').html() with the value returned from mains. How do I do that?

标签: backbone.js
2条回答
来,给爷笑一个
2楼-- · 2019-07-09 04:40

The general pattern for this sort of thing in Backbone is:

  1. create a model or collection
  2. pass that model/colleciton to a view
  3. that view registers an event handler on the model/collection
  4. the model/collection triggers an AJAX request (probably in response to a fetch call)
  5. the view's event handler is triggered
  6. the view's event handler updates the page

So, as mu is too short suggested, your best bet is to follow this pattern and have your view bind a handler to your collection's reset event.

It's worth mentioning however that reset won't always be the event you want to bind. For instance, you might not want to respond an AJAX request unless it changed attribute 'X' of the model. In that case you could instead bind to change:X, and then your handler would only be triggered if the AJAX response changed X.

To see all your possible options, see:

http://documentcloud.github.com/backbone/#Events-catalog

查看更多
该账号已被封号
3楼-- · 2019-07-09 04:42

You were on the right track just needed to have the view listening to the Collection rather than the collection listening to the view.

The below is your code with the slight modification of who listens to who.

Why? Ideally we want the Collections to know nothing of the Views.

(function() {
    window.App = {
        Models: {},
        Collections: {},
        Views: {},
        Router: {}
    };

    window.template = function(id) {
        return _.template( $('#' + id).html() );
    };

    App.Models.Main = Backbone.Model.extend({
        defaults : {
            FName: ''
        }
    });

    App.Collections.Mains = Backbone.Collection.extend({
        model: App.Models.Main,

        url: '../leads/main_contact'
    });

    App.Views.Mains = Backbone.View.extend({
        tagName: 'ul',
        initialize : function(){
          this.collection.on('reset', this.render, this);
        },
        render: function() {
            var ul = this.collection.each(this.addOne, this);
            return ul;
        },
        addOne: function(main) {
            var mainC = new App.Views.Main({ model: main});
            this.$el.append(mainC.render().el);
            return this;
        }
    });

    App.Views.Main = Backbone.View.extend({
        tagName: 'li',
        template: template('mainContactTemplate'),
        render: function () {
            this.$el.html(this.template(this.model.toJSON()));
            return this;
        }

    });

    mains = new App.Collections.Mains();
    main = new App.Views.Main( {'collection' : mains} );
    mains.fetch(); 

})();
查看更多
登录 后发表回答