将elenium.js视图附加到现有元素上,而不是将el插入DOM中


72

我正在实现我的第一个实际的非教程式Backbone应用程序,并且对使用bbone.js方面的使用存在两个疑问,这对我来说不太好,这涉及将视图的渲染el注入DOM与使用的现有元素el。我怀疑我会在这里为大家提供一些“可教的时刻”,并感谢您的帮助。

我在网络上看到的大多数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。我以几种不同的方式看到了它。因此,我的第一个问题是:调用视图的render方法并将其el插入DOM的适当位置在哪里?(不一定是同一地点)。我已经看到它是在路由器中,视图的初始化或渲染函数中或仅在根级文档就绪函数中完成的。($(function ())。我可以想象其中的任何一项工作,但是有正确的方法吗?

其次,我从一些HTML标记/线框开始,然后将html部分转换为与主干视图相对应的js模板。我觉得与其让视图呈现一个未附加的元素并在html中提供锚点以将其插入,还不如让它看起来更自然,当一个视图只包含一个元素并且不会消失时,使用现有的空包装器元素(通常是adivspanel本身。这样,我不必担心在文档中找到插入我未附加的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>

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

谢谢

Answers:


54

将视图附加到现有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大师。

玩得开心!


1
另外,感谢您提供使用模块模式的提示。我一直在调情require.js作为实现模块和动态加载以及所有这些好东西的方法,但是我们使用了许多非AMD插件和现有代码,因此我觉得保留它可能更简单,更不易出错在文件和模块中有意义的事物,请尽可能使用上面指示的模块模式之类的东西,并合并/缩小它们以进行生产。
B罗伯斯特

1
绝对,require.js是一个很棒的解决方案,但是它绝对是棘手的。通常,我只会使用模块模式之类的模式,然后使用命名空间将其置于窗口之外。很高兴我能帮助你!
jcreamer898

感谢您指出正确的方向。还发现$(this.el)的工作方式与此不同。$ el
Aleksy Goroszko 2014年

@eleksyGoroszko this。$ el与$(this.el)有何不同?
jcreamer898

18

您还可以将HTML DOM元素对象作为选项的'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')
    });
});

4
正是我要找的答案。谢谢!
zachwill


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.