Backbone加载视图中的视图(作为部分)

时间:2013-06-14 11:28:41

标签: javascript jquery backbone.js underscore.js

希望有人可以帮助我,

我有一个Backbone视图,它基本上是HTML的骨架,HTML构建一个标签界面,每个标签显然都有一个链接和内容区域。我想要的是每个内容呈现一个特定于该选项卡的单独的Backbone模板。

例如,在标签#briefs中,我想呈现app.projectBriefsView。我不能为了生活,我将如何做到这一点,这是我的“基础/主人”视图,我想加载其他所有。

app.ProjectsTabsView = Backbone.View.extend({

    el: "header.project",

    template: _.template($("#tpl-projects-tabs").html()),

    events: {
        'click .js-tab-link': 'showTab',
    },

    initialize: function() {
        this.render();
        var briefView = new app.projectBriefView;

        briefView.render().el;
    },

    render: function() {

        this.$el.append(this.template());


        return this;
    },

    showTab: function(el) {
        var tabRequired = $(el.currentTarget).attr("href");
        console.log(tabRequired);
        $(".tab-content.active").css("display", "none").removeClass("active");
        $(".tab-content"+tabRequired).addClass("active").css("display", "block");

        el.preventDefault();
    }

});

模板

<script type="text/template" id="tpl-projects-tabs">    
    <div class="tabs">
        <ul>
            <li><a href="#brief" class="tab-link js-tab-link active">Brief + Notes</a></li>
            <li><a href="#dates" class="tab-link js-tab-link">Dates</a></li>
            <li><a href="#files" class="tab-link js-tab-link">Files</a></li>
            <li><a href="#tasks" class="tab-link js-tab-link">Tasks</a></li>
            <li><a href="#messages" class="tab-link js-tab-link">Messages</a></li>
            <li><a href="#comments" class="tab-link js-tab-link">Comments</a></li>
        </ul>
        <div class="tab-content js-tab-content active" id="brief">Briefs</div>
        <div class="tab-content js-tab-content" id="dates">Dates</div>
        <div class="tab-content js-tab-content" id="files">Files</div>
        <div class="tab-content js-tab-content" id="tasks">Tasks</div>
        <div class="tab-content js-tab-content" id="messages">Messages</div>
        <div class="tab-content js-tab-content" id="comments">Comments</div>
    </div>
</script>

这是我想要加载到.tab-content#brief区域的视图。

app.projectBriefView = Backbone.View.extend({
el: ".tab-content",

template: _.template($("#tpl-brief-notes").html()),

events: {

},

initialize: function() {
    this.render();
},

render: function() {

    this.$el.append(this.template({
        p: app.project.toJSON()
    }));

    return this;
}

});

模板

<script type="text/template" id="tpl-brief-notes">
    <div class="project_info_content">
        <!-- New brief form -->
        <div class="brief">
            <h4>Brief</h4>
            <% if (p.is_owner) { %>
                <div class="js-brief-text"> 
            <% if (p.brief == undefined || p.brief == '') { %>
                <p class="add-text">No Brief, Click to add</p>
                <% } 
                } else { %>
                <div>
            <% } 
                    if (p.brief != undefined || p.brief != '') { %>
                    <% //p.brief %>
                        <?= nl2br(str_replace('  ', ' &nbsp;', htmlspecialchars($project['brief']))); ?>
                    <% } %>
                </div>
                <div class="inline-edit">
                    <% if (p.is_owner) { %> 
                        <form action="<?= base_url(); ?>projects/edit_brief/<%= p.id %>" method="post" accept-charset="utf-8" class="inline_edit edit_brief" novalidate="novalidate">
                            <p>
                                <textarea name="brief" class="brief_edit"><%= p.brief %></textarea>
                                <input type="submit" name="submit" value="Update"><a class="cancel" href="#">Cancel</a>
                            </p>
                        </form>
                    <% } %>
                </div>
            </div>
            <!-- End of new brief form -->
            <!-- New additional notes form -->
            <div class="additional_notes">
                <h4>Additional notes <span class="instructions">(Editable by other users)</span></h4>
                <div class="js-notes-text">
                    <%
                    if (p.additional_info == undefined || p.additional_info == '') { %>
                        <p class="add-text">No Notes, Click to add</p>
                    <% } else { %>
                    <% // p.additional_info %>
                    <?= nl2br(str_replace('  ', ' &nbsp;', htmlspecialchars($project['additional_info']))); ?>
                    <% } %>
                </div>
                <div class="inline-edit">
                    <form action="<?= base_url(); ?>projects/edit_additional_info/<%= p.id %>" method="post" accept-charset="utf-8" class="inline_edit edit_notes" novalidate="novalidate">                 <p>
                        <textarea name="text_details" class="notes_edit"><%= p.additional_info %></textarea>
                        <input type="submit" name="submit" value="Update">                      <a class="cancel" href="#">Cancel</a>
                    </p>
                    </form>
                </div>
            </div>
        </div>
        <!-- End of new additional notes form -->
    </div>
</script>

我认为在渲染函数的app.ProjectTabsView中我可以做类似的事情,

var brief = new app.projectBriefView(); brief.render().el();

将输出抛出到浏览器,但这似乎不起作用。有没有更好的方法来处理我在Backbone中称为部分视图的方式?如何让我偏爱浏览器?

1 个答案:

答案 0 :(得分:1)

由于Backbone视图可以动态地使用html填充浏览器,因此您只需要为内容添加一个div元素。然后,此div元素将用作管理选项卡的视图生成的嵌套视图的占位符。

我必须解决一个非常类似的问题,这就是我所做的:

首先,定义一个控件结构,将标签标题绑定到视图构造函数:

var Tab = function( title, viewConstructor ) {
      this.title = title;
      this.viewConstructor = viewConstructor;
    };

_.extend( Module.prototype, {
  render : function( options ) {
    this.view = new this.viewConstructor( options );
    return this.view.render();
  },
  close  : function() { 
    if( this.view ) {
      this.view.close();
    }
  }
});

然后,在数组中定义所有选项卡:

var tabs = [
  new Tab('brief', app.projectBriefView),
  new Tab('dates', app.projectDatesView),
  //...
]

你需要清理一下你的模板:

<script type="text/template" id="tpl-projects-tabs">    
  <div class="tabs">
    <ul>
        <li><a href="#brief" id="brief" class="tab-link js-tab-link active">Brief + Notes</a></li>
        <li><a href="#dates" id="dates" class="tab-link js-tab-link">Dates</a></li>
        <li><a href="#files" id="files" class="tab-link js-tab-link">Files</a></li>
        <li><a href="#tasks" id="tasks" class="tab-link js-tab-link">Tasks</a></li>
        <li><a href="#messages" id="messages" class="tab-link js-tab-link">Messages</a></li>
        <li><a href="#comments" id="comments" class="tab-link js-tab-link">Comments</a></li>
    </ul>
    <div class="tab-content js-tab-content" id="tab-content">Briefs</div>
  </div>
</script>

最后,您只需在活动中使用它们:

//...
showTabs : function( event ) {
  event.preventDefault();

  var clicked = $(el.currentTarget),
      title = clicked.attr("href").replace("#", ""),
      tab = _.findWhere( tabs, { title : title });

  // always cleanup the preceding tab.
  if ( this.activeTab ) {
    this.activeTab.close();
  }

  this.activeTab = tab;
  this.$('ul > li > .active').removeClass('active');      
  this.$('#tab-content').html( tab.render().el );
  clicked.addClass('active');
}