Javascript 什么';这是确定主干是否存在的正确方法。查看';是将此.el附加到文档还是浮动?

Javascript 什么';这是确定主干是否存在的正确方法。查看';是将此.el附加到文档还是浮动?,javascript,backbone.js,Javascript,Backbone.js,我尝试使用模板最初呈现视图,但在后续调用中更新视图(当视图是文档的一部分时) 我的应用程序页面看起来有点像 <body> <!-- ... --> <div id="view_placeholder"/> <!-- ... --> </body> 这样做的原因是模板包含相当多的节点,每次更改都重新生成它是不可行的 我已经研究了一些数据绑定库,例如,但它们不适合模板:模型关系 我注意到的一件事是,在我将其添加到文档之前,th

我尝试使用模板最初呈现视图,但在后续调用中更新视图(当视图是文档的一部分时)

我的应用程序页面看起来有点像

<body>
  <!-- ... -->
  <div id="view_placeholder"/>
  <!-- ... -->
</body>
这样做的原因是模板包含相当多的节点,每次更改都重新生成它是不可行的

我已经研究了一些数据绑定库,例如,但它们不适合模板:模型关系

我注意到的一件事是,在我将其添加到文档之前,
this.el.parentNode==null
,但我不确定这是否是一个确定的测试,并且在任何情况下,如果我将此视图包装到另一个视图中,那么该测试就变得不那么有用了(或者我可能过于谨慎,因为在另一个视图的el中,我已经渲染了我的子模板

我可以看到的另一个选项是使用字段跟踪渲染状态,例如

Backbone.View.extend({
  //
  templateRendered:false,
  // ...
  render: function() {
    if (!this.templateRendered) {
      // render the contents from the template
      this.templateRendered = true;
    } else {
      // update the content visibility based on the model
    }
  },
  // ...
});
但我觉得这很讨厌

所以我的问题是:


跟踪以下事实的最佳方法是什么:我已经完全渲染了模板,因此只需要调整渲染的模板,而不是重新渲染它(并重新插入所有子视图)?

我认为惯用的主干方法是只调用完整的
渲染()
在视图上进行完整渲染时,使用模型更改事件绑定调用渲染视图较小部分的子渲染函数

var AddressView = Backbone.View.extend({
    initialize: function (options) {
        Backbone.view.prototype.initialize.call(this, options);
        _.bindAll(this)
        options.model.on('change:name', this.renderName);
        options.model.on('change:street', this.renderStreet);
        options.model.on('change:zipCode', this.renderZipCode);
    },
    renderName: function (model) {
        this.$el.find("#name").text(model.get("name"));
    },
    renderZipCode: function (model) {
        this.$el.find("#zipcode").text(model.get("zipCode"));
    },
    renderStreet: function (model) {
        this.$el.find("#stree").text(model.get("street"));
    },
    render: function () {
        //Populate this.el with initial template, subviews, etc
        //assume this.template is a template function that can render the main HTML
        this.$el.html(this.template(model));
        this.renderName(this.model);
        this.renderZipCode(this.model);
        this.renderStreet(this.model);
        return this;
    }
});

上面的代码无疑是单调乏味的。我会重新考虑,或者,就我个人而言,但我相信上面的模式是规范的vanilla backbone.js方法。

我会在视图的元素即将插入之前避免渲染视图。在任何情况下,您都可以通过检查视图元素的父级,即

 this.$el.parent()

如果
this.$el
不是您文档的一部分,则应为空。

我正在玩弄
this.el.parentNode!=null&&this.el.children.length()>0
,这是一个很好的测试,可以测试节点是否正确呈现并插入到应该超出的位置。您可以使用“延迟加载”在渲染函数第二次运行时替换它,这样您就不会每次都运行检查。您是否在问?不完全是因为元素中也填充了内容…然后我需要考虑是否有人调用
this.setElement()
传递一个非空元素进行包装…虽然我可能会让这对我自己来说太复杂;-)这种技术的问题是,它迫使我在需要
渲染()时思考
call…鉴于此特定视图所做的只是显示/隐藏子视图,后期初始渲染路径将很快。我不愿意为此拉铆钉,因为一些子视图使用铆钉,两组绑定可能会导致问题…哦,好吧…我将看看是否能想出更好的方法…如果不能,我将接受此答案;-)@StephenConnolly您也可以只绑定到
更改
事件本身,并在那里使用您的*post initial render`路径,例如,您可以创建一个
refresh()
方法并将所有更改绑定到该方法。因此需要考虑的一点是良好的封装。视图的任务是获取模型数据并将其呈现为this.el中的HTML。时期视图不应该关心el是否连接到DOM(理想情况下)。主干网的设计围绕着视图是哑的、模型充当发布/订阅事件总线,以及由模型触发的事件触发的所有内容。我并不是说这是最终的架构,但它是如何设计主干的工作,当有疑问时,尽量坚持基本原则。
 this.$el.parent()