hashbang在硬刷新时没有正确刷新页面

时间:2011-08-11 17:28:42

标签: javascript backbone.js

我正在使用Rails构建一个backbone.js应用程序3.当我显示产品列表并点击顶部的产品时,我会看到网址

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>

1 个答案:

答案 0 :(得分:1)

你很可能会收到一条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});

现在,当页面加载并执行你的javascript时,无论执行什么路线,都会始终创建“window.App.appView”。