【问题标题】:The backbone router isn't working properly骨干路由器工作不正常
【发布时间】:2013-06-25 22:03:58
【问题描述】:

我正在构建一个简单的主干应用程序,它有 4 条路线:主页、关于、隐私和条款。但在设置路线后,我遇到了 3 个问题:

“条款”视图未呈现;

当我刷新#about 或#privacy 页面时,主页视图在#about/#privacy 视图之后呈现

当我点击返回按钮时,主页视图永远不会呈现。例如,如果我在#about 页面中,并且我点击返回按钮返回主页,about 视图将停留在页面中

我不知道我在第一个问题上做错了什么。我认为第二个和第三个问题与家庭路由器中缺少的东西有关,但我不知道是什么。

这是我的代码:

HTML

<section class="feed">

    <script id="homeTemplate" type="text/template">

        <div class="home">
        </div>

    </script>

    <script id="termsTemplate" type="text/template">

        <div class="terms">
        Bla bla bla bla
        </div>

    </script>   

    <script id="privacyTemplate" type="text/template">

        <div class="privacy">   
        Bla bla bla bla
        </div>

    </script>

    <script id="aboutTemplate" type="text/template">

         <div class="about">
         Bla bla bla bla
         </div>

    </script>

</section> 

观点

app.HomeListView = Backbone.View.extend({
    el: '.feed',

    initialize: function ( initialbooks ) {
         this.collection = new app.BookList (initialbooks);
         this.render();
    },

    render: function() {
         this.collection.each(function( item ){
         this.renderHome( item );
         }, this);
    },

    renderHome: function ( item ) {
         var bookview = new app.BookView ({
         model: item
         })
         this.$el.append( bookview.render().el );
         }  });

app.BookView = Backbone.View.extend ({
    tagName: 'div',
    className: 'home', 

     template: _.template( $( '#homeTemplate' ).html()),

    render: function() {
         this.$el.html(this.template(this.model.toJSON()));
         return this;
         }  
 });

app.AboutView = Backbone.View.extend({
     tagName: 'div',
     className: 'about',

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

     template: _.template( $( '#aboutTemplate' ).html()),

     render: function () {
         this.$el.html(this.template());
         return this;
     }
});

 app.PrivacyView = Backbone.View.extend ({
     tagName: 'div',
     className: 'privacy',

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

     template: _.template( $('#privacyTemplate').html() ),

     render: function () {
         this.$el.html(this.template());
         return this;
     }
});

 app.TermsView = Backbone.View.extend ({
     tagName: 'div',
     className: 'terms',

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

     template: _.template ( $( '#termsTemplate' ).html() ), 

     render: function () {
         this.$el.html(this.template()),
         return this;
     }
 });

还有路由器:

var AppRouter = Backbone.Router.extend({
     routes: {
         '' : 'home',
         'about' : 'about',
         'privacy' : 'privacy',
         'terms' : 'terms'
     },

     home: function () {
         if (!this.homeListView) {
             this.homeListView = new app.HomeListView();
         };
     },

     about: function () {
         if (!this.aboutView) {
             this.aboutView = new app.AboutView();
        };
         $('.feed').html(this.aboutView.el);
     },

     privacy: function () {
         if (!this.privacyView) {
             this.privacyView = new app.PrivacyView();
         };
         $('.feed').html(this.privacyView.el);
     },

     terms: function () {
          if (!this.termsView) {
             this.termsView = new app.TermsView();
         };
         $('.feed').html(this.termsView.el);
     }
 })

 app.Router = new AppRouter();
 Backbone.history.start(); 

我错过了一些东西,但我不知道是什么。

谢谢

【问题讨论】:

    标签: javascript backbone.js backbone-views backbone-routing


    【解决方案1】:

    我认为您需要将脚本模板移出 .feed html 元素,当您呈现 HomeListView 视图时,它将删除其 el 中的所有内容,然后脚本模板将不可用于您调用的其他视图 iside的 HomeListView。

    <section class="feed">
    
    
    
    </section>
    <script id="homeTemplate" type="text/template">
    
        <div class="home">
        </div>
    
    </script>
    
    <script id="termsTemplate" type="text/template">
    
        <div class="terms">
        Bla bla bla bla
        </div>
    
    </script>   
    
    <script id="privacyTemplate" type="text/template">
    
        <div class="privacy">   
        Bla bla bla bla
        </div>
    
    </script>
    
    <script id="aboutTemplate" type="text/template">
    
         <div class="about">
         Bla bla bla bla
         </div>
    
    </script> 
    

    您在 termsView 的渲染函数中也缺少一个冒号

      render: function () {
         this.$el.html(this.template());
         return this;
      }
    

    【讨论】:

    • 感谢您的回答,我尝试了您的建议,但我仍然遇到同样的问题。
    • 您在 termsView 的渲染函数中也缺少一个冒号
    • 控制台中的错误是这个:Uncaught SyntaxError: Unexpected token return。我在 termsView 中缺少冒号的地方?
    • 在您的渲染函数中,您在这一行缺少它 this.$el.html(this.template()),
    • 我已经发现了丢失的冒号。这样第一个问题就解决了。谢谢!现在我需要解决另外两个问题
    【解决方案2】:

    除了 Rayweb_on 建议的所有内容之外,从 AboutViewPrivacyViewTermsViewinitialize 方法中删除对 render 的调用,并在您的路由函数中,将 $('.feed').html(this.aboutView.el); 等替换为$('.feed').html(this.aboutView.render().el);

    另外,在您的路由器中定义一个名为currentView 或类似名称的变量,并将其设置为您的路由函数选择的任何视图。在每个路由函数中,检查是否已设置,如果已设置,请在渲染新视图之前对其调用 remove()。这些更改应防止先前渲染的视图踩到新视图,并确保新渲染的视图是最新的。

    【讨论】:

    • 感谢您的回答。如何将 currentView 设置为路由函数选择的任何视图,如何检查每个路由函数是否已设置并在渲染新视图之前调用 remove()?很抱歉,但我仍在学习 Backbone,因此欢迎提供更多帮助。谢谢
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多