Javascript Backbone.js DOM不是';t准备好在渲染方法中应用jquery魔术

Javascript Backbone.js DOM不是';t准备好在渲染方法中应用jquery魔术,javascript,backbone.js,Javascript,Backbone.js,我正在尝试建立一个包含多个列表的待办事项列表。一切都很好。当我想使用jQueryUISortable时,就会出现这个问题。 我正在render函数中的TaskListView中添加代码段,但我必须将其包装到setTimeout函数中,以便它等待DOM加载 我很确定有更好的方法,但我就是找不到。谢谢你的帮助 var TaskView = Backbone.View.extend({ initialize: function(task) { this.task = task;

我正在尝试建立一个包含多个列表的待办事项列表。一切都很好。当我想使用jQueryUISortable时,就会出现这个问题。 我正在render函数中的TaskListView中添加代码段,但我必须将其包装到setTimeout函数中,以便它等待DOM加载

我很确定有更好的方法,但我就是找不到。谢谢你的帮助

var TaskView = Backbone.View.extend({
    initialize: function(task) {
        this.task = task;
    },
    render: function() {
        var completedClass = "completedTask";
        if (this.task.completed == 100) completedClass = "pendingTask";
        var html = ""
        + "<li class='task-<%= task.get('id') %> ' data-id='<%= task.get('id') %>' sortable='true'>"
        + "<div class='float-left'><i class='icon-trash removeTask' data-id='<%= task.get('id') %>'></i></div>"
        + "<div class='float-left'>"
        + "<span class='editTask ' data-type='title' data-id='<%= task.get('id') %>'><%= task.get('title') %></span> "
        + "</div>"
        + "<div class='float-right'>"
        + "<span class='editTask task-responsible label' data-type='responsible' data-id='<%= task.get('id') %>'><%= task.get('responsible') %></span>"
        + "<span class='editTask task-deadline label' data-type='ended' data-id='<%= task.get('id') %>'><%= task.get('ended') %></span>"
        + "<span class='label criticallyLevelToggle editTask <%= criticallyLevelClass %>' data-type='completed' data-id='<%= task.get('id') %>'><%= parseInt(task.get('completed')) %>%</span>"
        + "</div>"
        + "<div class='clear'>&nbsp;</div>"
        +"</li>";

        var template = _.template( html, {task: this.task, criticallyLevelClass:this.task.getCriticallyLevelClass(), completed: completedClass});
        this.$el.html(template);
        return this;
    }
});

var TaskListView = Backbone.View.extend({
    initialize: function(tasks) {
        this.tasks = tasks;
    },
    render: function() {
        var html = ""
        +"<ul class='tasks'>"
        +"<%= tasksli %>"
        +"<li><div class='float-left'><input type='text' placeholder='New task...' class='new-task' name='new-task'/></div><div class='clear'>&nbsp;</div></li>"
        +"</ul>";
        + "";
        var tasksRendered = "";
        if (_.isArray(this.tasks)) {
            for (var i = 0; i < this.tasks.length; i++) {
                var tView = new TaskView(new Task(this.tasks[i]));
                tasksRendered += tView.render().el.innerHTML;
            };
        }
        var template = _.template(html, { tasksli: tasksRendered});
        this.$el.html(template);

        setTimeout(function(){this.$('.tasks').sortable({
            stop: function(e, ui) {
                ui.item.trigger('drop', ui.item.index());
            }
        });}, 500);

        return this;
    }
});
var TaskView=Backbone.View.extend({
初始化:函数(任务){
this.task=任务;
},
render:function(){
var completedClass=“completedTask”;
如果(this.task.completed==100)completedClass=“pendingTask”;
var html=“”
+“
  • ” + "" + "" + " " + "" + "" + "" + "" + "%" + "" + " " +“
  • ”; var-template=389;.template(html,{task:this.task,criticallyLevelClass:this.task.getCriticallyLevelClass(),completed:completedClass}); 这个.$el.html(模板); 归还这个; } }); var TaskListView=Backbone.View.extend({ 初始化:函数(任务){ 这个。任务=任务; }, render:function(){ var html=“” +“
      ” +"" +“
    • ” +“
    ”; + ""; var tasksRendered=“”; if(u.isArray(this.tasks)){ for(var i=0;i
    而不是
    setTimeout
    ,只需使用
    $(function(){})
    (或
    $(document).ready
    ),就像您通常等待DOM就绪一样。这些函数没有什么特别之处,您可以随时向它们添加新回调。您所要担心的就是在回调中维护
    这个
    的含义

    render: function() {
        var html = ""
        +"<ul class='tasks'>"
        +"<%= tasksli %>"
        +"<li><div class='float-left'><input type='text' placeholder='New task...' class='new-task' name='new-task'/></div><div class='clear'>&nbsp;</div></li>"
        +"</ul>";
        + "";
        var tasksRendered = "";
        if (_.isArray(this.tasks)) {
            for (var i = 0; i < this.tasks.length; i++) {
                var tView = new TaskView(new Task(this.tasks[i]));
                tasksRendered += tView.render().el.innerHTML;
            };
        }
        var template = _.template(html, { tasksli: tasksRendered});
        this.$el.html(template);
        var self = this;
    
        $(function(){
            self.$('.tasks').sortable({
            stop: function(e, ui) {
                ui.item.trigger('drop', ui.item.index());
            }
        })
    
        return this;
    }
    
    render:function(){
    var html=“”
    +“
      ” +"" +“
    • ” +“
    ”; + ""; var tasksRendered=“”; if(u.isArray(this.tasks)){ for(var i=0;i

    或者,(可能更正确地说)采取步骤确保主干视图在DOM就绪之前不会调用其
    render
    方法。

    您可能需要使用
    $(document).ready(函数(){//your code here});
    要解决这个问题,提示:您可以将以下内容添加到您的HTML:[插入HTML代码]中,而不是在JS中连接HTML。在javascript中使用:template:。.template($('.#我的模板').HTML())Hazaart:谢谢……我会看一看。这会让一切更具可读性;)@米格尔:那我该怎么做呢?例如,确保DOM在调用渲染函数(->这就是我要找的)。在某个地方,你正在实例化视图、路由器或其他触发视图渲染的东西。不要这样做,除非在
    $(function(){…})中
    回调。可能只需将
    主干.history.start()
    移动到
    $(函数(){})
    中即可。我认为问题在于,在我的小视图到达DOM之前调用.sortable()函数(DOM已呈现为完整).现在我不明白如何阻止这种流?…它不是每次运行时通过这一段时都会触发吗?我修复了它。问题是我没有正确使用视图。我将子视图渲染为字符串,并在父视图中使用它。显然这不起作用。现在我使我的视图和子视图主干兼容,并且现在工作正常。希望看到您的固定代码。阅读您的评论后,我想我可能也犯了同样的错误。