【问题标题】:How to reference collection's data in render() when fetched in initialize() in BackboneJS?在 BackboneJS 中的 initialize() 中获取时如何在 render() 中引用集合的数据?
【发布时间】:2016-10-25 18:26:13
【问题描述】:

当视图调用多个集合(一些只需要最初获取,一些由事件触发)时,我试图了解组织视图的正确方法。

我有一个集合“Genres_collection()”,它从数据库中获取流派列表:

Genres_collection:

define([
    'jquery',
    'underscore',
    'backbone',
    'models/genre_model'
],function($,_,Backbone,Genre_model){
    var Genres_collection = Backbone.Collection.extend({
        model: Genre_model,
        url: '/api/genres',
        parse: function(response){
          return response;
        }
    })
    return Genres_collection;
});

流派模型:

define([
    'jquery',
    'underscore',
    'backbone'
],function($,_,Backbone){
    var Genre_model = Backbone.Model.extend({
        defaults: {
            'title': 'Untitled Track'
        }
    })
    return Genre_model;
});

我有一个视图,除其他外,我想在 initialize() 上获取流派,然后在渲染中引用集合的数据。据我了解,initialize 仅在视图被初始化(因此得名)并且 render() 被调用任意次数(即:触发事件时)时才会触发。所以,我的想法是,当采取行动时,渲染用于渲染和“重新渲染”视图。

因此,我有以下查看代码:

搜索视图:

define([
    'jquery',
    'underscore',
    'backbone',
    'collections/tracks',
    'collections/genres',
    'text!templates/search_view_title.html',
    'text!templates/search_view.html'
],function($,_,Backbone,Tracks_collection,Genres_collection,Search_view_title_template,Search_view_template){
    var Search_view = Backbone.View.extend({
        el: $('#app'),
        
        initialize: function(){
            this.collection = new Tracks_collection();
            this.genre_collection = new Genres_collection();
            this.genre_collection.fetch();
        },
        search: function(searchtype){
            switch(searchtype){
                case 'genre':
                    console.log('genre changed');
                    this.collection.fetch({
                        data: {limit: 30, type:'genre',genre_id:$('#genre_select').val()}
                    });
                break;
                case 'search':
                    console.log('search changed');
                    this.collection.fetch({
                        data: {limit: 30, type:'search',keyword:$('#keyword').val()}
                    });
                break;
            }
        },
        render: function(){
            // MAKE 'THIS' ACCESSIBLE
            var that = this;

            
            console.log(this.genre_collection);

            var template = _.template(Search_view_template);
            var template_vars = {genres: this.genre_collection};
            console.log(template_vars);
            var template_html = template(template_vars);
            that.$el.find('#container').html(template_html);
            


            this.collection.bind('add',function(collection){
                console.log('collection has been changed');
            })
                      
        }
    });

    return Search_view;

});

但是,当我尝试将 render() 中的genre_collection 打印到控制台或将其传递给模板时,我没有从在 initialize() 中获取的集合中获取数据。

  1. 这是组织此类呼叫的正确方法吗?
  2. 哪里出了问题?如何让它在 render() 中传递 this.genre_collection 中的数据?

我正在使用 requirejs,我可以确认正在调用 initialize() 和 render() 调用,因为我编写了更简单的视图,可以很好地执行代码。

【问题讨论】:

    标签: javascript jquery backbone.js requirejs backbone-views


    【解决方案1】:

    在这种情况下,你应该写你的this = that

    console.log(that.genre_collection) 
    

    而不是

    console.log(this.genre_collection);
    

    将此添加到您的初始化函数中

    this.listenTo(this.genre_collection , 'change', this.render);
    

    您可以更改您的genre_collection 解析nmethod,以便它返回您的数据

    parse: function(response){
        return response.genres
    }
    

    【讨论】:

    • 这没有任何区别。这和那是相同的,因此 this.genre_collection = that.genre_collection
    • 不,只是一个对象。如果我将 .fetch() 分配给一个变量,我会得到另一个对象,该对象将数据作为 responseText 和 responseJSON 存储在其中,但我不知道访问它的正确方法。
    • 对不起,这也没有什么不同。我了解您在那里尝试做什么,但我认为这不是解决方案。我根本无法引用来自 this.genre_collection.fetch() 的响应以传递到 render() 中的模板
    • 我最初有这个,但是因为我打算更新 this.collection,所以我不想在每次调用 render 时触发 this.genre_collection.fetch()。我认为在 itialize() 中获取初始集合是一个好主意,因为它只需要完成一次。如果我将 this.collection 的任何更改绑定到 render() 那么它会重新获取,但我想我可以使用不同的视图“方法”来处理它。
    • 这是一个绝妙的主意(这是正确的方法),这就是为什么 this.listenTo(this.genre_collection , 'reset', this.render);应该适合你,只需在 fetch 之前添加它。
    猜你喜欢
    • 1970-01-01
    • 2019-11-27
    • 2018-09-04
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多