backbone.js hashbang在硬刷新时未正确刷新页面

okxuctiv  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(141)

我正在使用Rails 3构建一个backbone.js应用程序。当我显示产品列表并单击顶部的产品时,我看到如下URL:

http://localhost:3010/#products/20

然而,当我硬刷新页面时,我看不到产品信息。在服务器端,我看到的不是对产品的json请求,而是以下内容

Started GET "/" for 127.0.0.1 at 2011-08-11 13:26:38 -0400
  Processing by HomeController#index as HTML

下面是我的JavaScript代码

$(function(){

  window.Product = Backbone.Model.extend({
    defaults: { name: 'name missing' },
    urlRoot: '/products'
  });

  window.ProductsList = Backbone.Collection.extend({
    model: Product,
    url: '/products'
  });

  window.ProductViewForListing = Backbone.View.extend({
    template: $('#productTmplForListing').template(),
    initialize: function() {
      _.bindAll(this, 'render');
    },
    className: 'product',
    render: function(){
      var fragment = $.tmpl(this.template, this.model.toJSON());
      $(this.el).html(fragment);
      return this;
    }
  });

  window.ProductViewForShow = Backbone.View.extend({
    template: $('#productTmplForShow').template(),
    initialize: function(){
      _.bindAll(this, 'render');
      this.render();
    },
    render: function(){
      var fragment = $.tmpl(this.template, this.model.toJSON());
      $(this.el).html(fragment);
      return this;
    }
  });

  window.AppView = Backbone.View.extend({
    el: $('#products'),
    initialize: function(){
      _.bindAll(this, 'render', 'showProduct');
      this.render();
    },
    render: function(){
      var targetElement = $('#products');
      var self = this;
      this.collection.each(function(product){
        var view = new ProductViewForListing({model: product}),
            fragment = view.render().el;
        self.el.append(fragment);
      });
    },
    showProduct: function(id){
      var product = new Product({id: id}), self = this;
      product.fetch({
        success: function(){
          var mainElement = self.el.closest('#main'),
              view = new ProductViewForShow({model: product});
          mainElement.find('#products').html('');
          self.el.append(view.render().el);
        },
        error: function(){ alert('error getting product details'); }
      });
      return false;
    }
  });

  window.products = new ProductsList();

  window.AppRouter = Backbone.Router.extend({
    initialize: function(){
    },
    routes: {
      '': 'home',
      'products/:id': 'showProduct'
    },
    home: function(){
      var self = this;
      window.products.fetch({
        success: function(){
          self.appView = new AppView({ collection: window.products });
          self.appView.render();
        }
      });
    },
    showProduct: function(id){
      window.App.appView.showProduct(id);
    }
  });

  window.App = new window.AppRouter();
  Backbone.history.start({pushState: false});

});

这是我的索引模板

<script type="text/x-jquery-tmpl" id="productTmplForListing">
  <a href="#products/${id}" data-id='${id}'>
    <img alt="${name}" class="productImage" height="190" src="/system/pictures/${id}/thumbnail/${picture_file_name}" width="190" />
  </a>
  <p class="productName">
    <a href="/products/${id}">
      ${name}
    </a>
  </p>
  <p class="productPrice">
    ${price}
  </p>
</script>
j1dl9f46

j1dl9f461#

您很可能会收到一个javascript错误,内容类似于“undefined没有一个名为'showProduct'的方法”,对吗?
问题在于您在路由器中创建“window.App.AppView”的方式。您仅在路由器命中缺省路由(“home”方法)时创建此对象。但当您查看“#/products/20”散列片段并在浏览器中单击刷新按钮时,路由器上的home方法不执行。仅执行showProduct路由。
这应该很容易修复,虽然。你需要移动“appView”的创建以外的你的路由器:

window.AppRouter = Backbone.Router.extend({
    initialize: function(){
    },
    routes: {
      '': 'home',
      'products/:id': 'showProduct'
    },
    home: function(){
      var self = this;
      window.products.fetch({
        success: function(){
          self.appView.render();
        }
      });
    },
    showProduct: function(id){
      window.App.appView.showProduct(id);
    }
  });

  window.App = new window.AppRouter();
  window.App.appView = new AppView({ collection: window.products });

  Backbone.history.start({pushState: false});

现在“window.App.appView”将在页面加载并执行javascript时创建,无论执行的是哪种路径。

相关问题