主干子视图未正确呈现

Backbone subview not rendered properly

本文关键字:视图      更新时间:2023-09-26

我开始使用 Backbone 开发一个网站.js经过整个上午的尝试,我非常困在以下问题上。

我在这里只输出相关的代码。

我有一个名为导航器的视图,其中包含一个记录集合(最初为空):

var NavigatorView = Backbone.View.extend({
    template: JST['app/scripts/templates/Navigator.ejs'],
    tagName: 'div',
    id: '',
    className: 'saiNavigator',
    events: {},
    initialize: function () {
        this.currentRecords = new RecordsCollection();
        this.currentRecords.on('reset', this.onRecordsCollectionReseted.bind(this));
    },
    onRecordsCollectionReseted: function(){
        this.render();
    },
    render: function () {
        var tplResult = this.template({
            computeTemplate: this.computeTemplate,
            records: this.currentRecords
        });
        this.$el.html(tplResult);
    },
    onDOMUpdated: function(){
        var me = this;
        var data = {
            device : 'web',
            gridId : this.model.get('gridId'),
            filterId : this.model.get('filterId')
        };
        $.ajax({
            url: App.getTokenedUrl() + '/task/getGridData.'+this.model.get('taskId')+'.action',
            success: me.onRecordReceived.bind(me),
            statusCode: {
                500: App.handleInternalError
            },
            type: 'GET',
            crossDomain: true,
            data : data,
            dataType: 'json'
        });
    },
    onRecordReceived: function(result){
        var newRecords = [];
        for(var i = 0; i < result.items.length; i++){
            var newRecord = new RecordModel(result.items[i]);
            newRecords.push(newRecord);
        }            
        this.currentRecords.reset(newRecords);
    }
});

我有一个名为 dossier 的视图,它是 html

<div id="dossier1" class="dossier">
  <div id="dossier1-navContainer" class="navigatorContainer"/>   
  <div class="pagesNavigatorContainer"/>
  <div class="pagesContainer"/>
  <div class="readOnlyFiche"/>
</div>

当我第一次渲染达析报告(我只渲染一次)时,我在以下渲染函数中创建导航器

render: function () {
    this.$el.html(this.template({
        uniqBaseId: this.id,
        className: this.className
    }));
    var nav = this.navigator = new NavigatorView({
        model : this.model,
        id: this.id+'navigator',
        el: $('#'+this.id+'-navContainer')
    });
    this.navigator.render();
    //We notify the navigator that it's ready. This will allow the nav to load records
        nav.onDOMUpdated();
    }
}

正如我们所看到的,我将"#dossier1-navContainer"ID提供给导航器,以便他在那里渲染

所以,这是它的工作原理。当我呈现达析报告时,它会创建一个导航器并将其插入 DOM 中。完成后,我通知导航器它可以通过 ajax 请求从服务器加载其数据。当我收到答案时,我用传入的记录重置了数据收集。

在导航器渲染函数中的 this.$el.html(tplResult) 之前,我输出结果字符串。

第一次

<div class="items"></div> 

第二次拿到唱片的时候,是

<div class="items">
    <div>item1</div>
    <div>item2</div>
    <div>item3</div>
</div> 

所以模板生成是正确的。但是,当第二次渲染发生时,this.$el.html(tplResult) 不执行任何操作。如果我在浏览器中查看 DOM,则没有任何变化

但是,如果我将此行替换为

$('#dossier1-navigator').html(tplResult) 

它有效。这意味着第一次 $('#dossier1-navigator') 和 this.$el 是同一个对象,第二次不是。

我不知道为什么它第二次不适用于标准 this.$el。

帮助!!

提前致谢

编辑:在与Seebiscuit讨论了很多之后,我添加了有助于回答问题的几行

newTask.render();
var taskHtml = newTask.$el.html();
$('#mainTaskContainer').append(taskHtml);

我的预感是你有一个绑定问题。我建议你替换

 this.currentRecords.on('reset', this.onRecordsCollectionReseted.bind(this)); },

在您的initialize中,具有:

this.listenTo(this.currentRecords, "reset", this.render);

无需特别绑定。Backbone 的 listenTo 将回调出价给设置侦听器的 Backbone 对象(this.listenTo 中的 this)。还有一个额外的好处,当你关闭视图(通过调用this.remove())时,它会删除侦听器,并帮助你避免僵尸视图。

试试吧。

我认为

问题是您没有使用传递给导航器视图的内容;

在您的导航器视图中,请尝试以下操作:

initialize:function(el) {
    this.$el=el
    ...
}

让我知道它是否有帮助

经过与seebiscuit的无数分钟讨论,我们提出了解决方案。问题完全在于$el元素的定义。正式定义将其定义为

视图元素的缓存 jQuery 对象。一个方便的引用,而不是一直重新包装 DOM 元素

从标准缓存的角度来看,这实际上不是很精确。从我的角度来看,至少缓存的原则是寻找没有值的值,否则使用它。但是,在这种情况下,情况并非如此。正如Seebiscuit告诉我的那样,

因为当你第一次绑定 this.$el = $(someelement) this.$el 将始终引用 $(someelement) 的返回,而不是 $(someelement)。什么时候差异很重要? 当您执行赋值时元素不在 DOM 中时

所以实际上,$el保存了选择器第一次查找的结果。因此,如果第一次查找未命中,那么它永远不会成功!即使稍后添加该元素。

我在这里的错误是在渲染其导航器视图子视图后将主达析报告添加到 DOM 中。如果$el是真正的缓存,我本可以找到解决方案,因为 ajax 回调中的第二个渲染会找到该元素。以目前的工作方式$el我一无所有。

结论:确保在尝试渲染子视图时,视图的每个部分都在 DOM 中正确呈现。