ChatGPT解决这个技术问题 Extra ChatGPT

将backbone.js 视图附加到现有元素与将el 插入DOM

我正在实现我的第一个实际的非教程 Backbone 应用程序,并且有两个关于使用 backbone.js 的方面的问题,这与我不太满意,这与将视图的渲染 el 注入 DOM 相关与为 el 使用现有元素相比。我想我会在这里为大家提供一些“可教的时刻”,并感谢您的帮助。

我在 web 中看到的大多数 Backbone View 示例在创建 View 时都指定了 tagName、id 和/或 className,从而创建了一个与 DOM 无关的 el。它们通常看起来像:

App.MyView = Backbone.View.extend({
    tagName: 'li',
    initialize: function () {
     ...
    },
    render: function () { 
        $(this.el).html(<render an html template>);
        return this;
    }
}); 

但是教程并不总是解释他们建议如何将渲染的 el 放入 DOM。我已经看到了几种不同的方式。所以,我的第一个问题是:调用视图的渲染方法并将其 el 插入 DOM 的合适位置在哪里? (不一定是同一个地方)。我已经看到它在路由器、视图的初始化或渲染函数中完成,或者只是在根级文档就绪函数中完成。 ($(function ())。我可以想象这些工作中的任何一个,但是有正确的方法吗?

其次,我从一些 HTML 标记/线框开始,并将 html 部分转换为与主干视图相对应的 js 模板。与其让视图渲染一个未附加的元素并在 html 中提供一个锚点来粘贴它,我觉得它更自然,当视图只有一个元素并且它不会消失时,使用现有的、清空的包装器元素(通常是 divspan)作为 el 本身。这样我就不必担心在文档中找到插入我未附加的 el 的位置,这可能最终看起来像这样(注意额外的分层):

<div id="insert_the_el_in_here">  <!-- this is all that's in the original HTML doc -->
    <div id="the_el">  <!-- i used to be a backbone generated, unattached el but have been rendered and inserted -->
        <!-- we're finally getting to some useful stuff in here -->
    </div>
 </div>

所以我的第二个问题的一部分是,对于一个基本静态的视图,直接使用页面 HTML 中的现有元素作为我的视图的 el 有什么问题吗?这样我就知道它已经在 DOM 中,在正确的位置,并且调用 render 将立即在页面上呈现视图。我会通过将已经存在的元素作为“el”传递给我的视图的构造函数来实现这一点。这样,在我看来,我不必担心将其粘贴到 DOM 中(使问题 1 变得毫无意义),并且调用 render 将立即更新 DOM。例如

<form>
   <div someOtherStuff>
   </div>
   <span id="myView">
   </span>
</form>

<script type="text/template" id = "myViewContents"> . . . </script>

<script type="application/javascript">
window.MyView = Backbone.View.extend( {
     initialize: function () {
          this.template = _.template($('#myViewContents').html());
          this.render(); 
     },
     render: function () {
          $(this.el).html(this.template());
          return this;
     }
});
$(function () {
    window.myView = new MyView({ el: $('#myView').get(0) });
});
</script>

对于页面上的静态视图,这是一种可行的方法吗?即,这些观点只有一种,在任何情况下都不会消失。或者,还有更好的方法?我意识到根据我使用视图的方式,可能有不同的方法(即在路由器中、在父视图中、在页面加载等),但现在我正在查看初始页面加载用例。

谢谢


j
jcreamer898

将视图附加到现有 DOM 节点的想法绝对没有错。

您甚至可以将 el 作为属性放在您的视图中。

window.MyView = Backbone.View.extend( {
     el: '#myView',
     initialize: function () {
          this.template = _.template($('#myViewContents').html());
          this.render(); 
     },
     render: function () {
          this.$el.html(this.template()); // this.$el is a jQuery wrapped el var
          return this;
     }
});
$(function () {
    window.myView = new MyView();
});

我的建议是,做有效的事...... Backbone 的美妙之处在于它很灵活,可以满足您的需求。

就常见模式而言,通常我发现自己有一个主视图来跟踪视图,然后可能是列表视图和单个项目视图。

就初始化而言,另一个常见的模式是拥有某种 App 对象来管理东西......

var App = (function ($, Backbone, global) {
    var init = function () {
        global.myView = new myView();
    };

    return {
        init: init
    };
}(jQuery, Backbone, window));

$(function () {
    App.init();
});

就像我之前说的,确实没有错误的做事方式,只要做有效的事。 :)

如果您需要更多帮助,请随时在 twitter @jcreamer898 上联系我,也可以查看 @derickbailey,他是一位 BB 大师。

玩得开心!


另外,感谢有关使用模块模式的提示。我一直在尝试使用 require.js 作为实现模块和动态加载以及所有这些好东西的方法,但是我们使用了如此多的非 AMD 插件和现有代码,我觉得保留它可能更简单且不易出错文件和模块中有意义的东西,尽可能使用您在上面指出的模块模式,并连接/缩小它们以用于生产。
当然,require.js 是一个很好的解决方案,但它肯定很棘手。通常我只会使用像模块模式这样的模式,然后使用命名空间来让事情远离窗口。很高兴我能帮上忙!
感谢您指出正确的方向。还发现 $(this.el) 与 this.$el 的工作方式不同
@AleksyGoroszko this.$el 与 $(this.el) 有何不同?
a
andho

您还可以将 HTML DOM Element 对象作为选项的 'el' 属性发送到视图中。

window.MyView = Backbone.View.extend( {
     initialize: function () {
          this.template = _.template($('#myViewContents').html());
          this.render(); 
     },
     render: function () {
          this.$el.html(this.template()); // this.$el is a jQuery wrapped el var
          return this;
     }
});
$(function () {
    window.myView = new MyView({
        el: document.getElementById('myView')
    });
});

正是我正在寻找的答案。谢谢!
d
deizel.

使用委托事件方法:

initialize: function() {
    this.delegateEvents();
}

要了解原因:http://backbonejs.org/docs/backbone.html#section-138 在“设置回调,在哪里”附近


p
pixelearth

看起来这些天你也可以使用setElement