【问题标题】:Backbone pre rendering of collection models集合模型的主干预渲染
【发布时间】:2015-09-05 03:45:50
【问题描述】:

我想在集合获取他的模型之后但在模型渲染之前执行一个操作,清除父元素。

我偶然发现了before and after render methods,但它们是特定于模型的,这将导致我的父元素在每次模型渲染之前都被清除。

我当然能够执行预取动作,但我希望它在完成提取和渲染模型之前发生。

我尝试使用监听集合的重置和更改事件,但都导致了不想要的最终结果。 重置事件接缝朝那个方向前进,但传递的参数是整个集合,而不是集合中的单个模型,因此由于参数类型的差异(集合而不是所需的模型),无法使用添加事件回调

任何想法如何在获取集合获取成功但模型尚未渲染时调用回调?

模型包含返回的属性,而集合包含用于获取和解析方法以返回参数包装对象的 url。

下面是我用来渲染集合视图的代码,它基本上是渲染集合中每个模型的视图。

Collection View
---------------
var FoosView = Backbone.View.extend({
        el: '#plans',
        events: {
            //'click tr': 'rowClick'
        },
        initialize: function() {
            this.listenTo(this.collection, 'add', this.renderNew);

            _.bindAll(this, "render");

            this.render();
        },
        renderNew: function(FooModel) {

            var item = new FooView({model: FooModel});
            this.$el.prepend(item.render().$el);
        }
        ...
    });

The model view
--------
var FooView = Backbone.View.extend({
        tagName: 'li',
        initialize: function(options) {
            this.options = options || {};
            this.tpl = _.template(fooTpl);
        },
        render: function() {
            var data = this.model.toJSON();

            this.$el.html(this.tpl(data));

            return this;
        }
    });

提前致谢。

【问题讨论】:

  • 嗨,Shahar,像弗朗索瓦一样,我不确定我是否理解您的问题。我认为您要求在集合重新加载/重置时清空父列表?您不能使用 renderNew() 方法,因为来自reset 事件的参数是模型列表而不是单个模型,对吗?所以你想使用this.listenTo(this.collection, 'reset', this.someNewMethod);,其中 someNewMethod 从清除列表开始,然后渲染元素。让我知道这听起来是否正确。
  • 我尝试使用 reset 但在渲染传递的参数时遇到问题,因为它是一个集合而不是单个模块(我尝试在 reset 回调中使用 renderNew 方法,我想这是我的错误...
  • 是的,看起来重置事件就是你想要的。我会为你提供一个答案,解释如何去做:)。

标签: backbone.js


【解决方案1】:

好的,我想我理解您的问题,这是一个建议的解决方案。您现在正在收听您收藏中的reset 事件并致电this.renderAllthis.renderAll 将从集合中获取模型列表并将它们呈现到页面,但仅在列表元素被清空之后。希望这会有所帮助:)。

var FoosView = Backbone.View.extend({
    el: '#plans',
    collection: yourCollection, // A reference to the collection.
    initialize: function() {
        this.listenTo(this.collection, 'add', this.renderNew);
        this.listenTo(this.collection, 'reset', this.renderAll);
    },
    renderAll: function() {
        // Empty your list.
        this.$el.empty(); 
        var _views = []; // Create a list for you subviews
        // Create your subviews with the models in this.collection.
        this.collection.each(function(model) {
            _views.push(new FooView({model: model});
        });
        // Now create a document fragment so as to not reflow the page for every subview.
        var container = document.createDocumentFragment();
        // Append your subviews to the container.
        _.each(_views, function(subview) {
            container.appendChild(subview.render().el);
        });
        // Append the container to your list.
        this.$el.append(container);
    },
    // renderNew will only run on the collections 'add' event.
    renderNew: function(FooModel) {
        var item = new FooView({model: FooModel});
        this.$el.prepend(item.render().$el);
    }
});

我不得不假设一些关于你 html 的事情,但我认为上面的代码应该足以让你启动并运行。让我知道它是否有效。

【讨论】:

  • 正是我的意图,我想这完全取决于我选择渲染的方式。抱歉@François Richard,我想我不够清楚:/
【解决方案2】:

我不完全确定你在问什么,但你试过了吗:

MyCollection.fetch({
    success: function(models,response) {
         //do stuff here
    }
});

您也可能有兴趣查看http://backbonejs.org/#Model-parse

希望对你有帮助!

编辑:获取和渲染之间没有直接联系我敢打赌,您将渲染绑定到模型更改。

使用===============>>>> http://backbonejs.org/#Model-parse

【讨论】:

  • 感谢您的回复,我确实尝试过,但成功调用是在渲染模型后进行的。我想在 fetch 成功后调用一个函数,但模型尚未渲染到 DOM。这是可选的吗?
  • 你定义了渲染,所以我无法告诉没有代码发生了什么,你是如何定义你的渲染的?
  • 我已经更新了用于渲染集合视图的代码,它只是简单地渲染集合中的每个模型。让我知道是否需要其他任何东西来完成这个谜题:)。谢谢。为每个检索到的模型调用 renderNew 方法,因此对于我想要执行的重置行为不是可选的(在模型渲染之前清除父元素。
  • 使用 .parse 方法
  • 您从集合中更改事件将在 aprse 之后触发,因此您可以在渲染之前对其进行处理
猜你喜欢
  • 2015-03-13
  • 1970-01-01
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 2015-05-30
  • 1970-01-01
  • 2015-08-31
  • 1970-01-01
相关资源
最近更新 更多