简体   繁体   English

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

[英]hashbang is not refreshing the page correctly when hard refresh

I am building a backbone.js application with Rails 3. When I display the list of products and click on a product at the top I see url like我正在使用 Rails 3 构建 backbone.js 应用程序。当我显示产品列表并单击顶部的产品时,我看到 url 之类的

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

However when I hard refresh the page I do not see product information.但是,当我硬刷新页面时,我看不到产品信息。 On the server side instead of a json request for product I see following在服务器端,而不是对产品的 json 请求,我看到以下

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

Here is my JavaScript code这是我的 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});

});

Here is my index template这是我的索引模板

<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>

You're most likely getting a javascript error that says something like "undefined does not have a method called 'showProduct'", right?您很可能会收到 javascript 错误,上面写着“未定义的没有名为 'showProduct' 的方法”,对吧?

the problem is the way you're creating the "window.App.AppView" in your router.问题是您在路由器中创建“window.App.AppView”的方式。 you're only creating this object when the router hits the default route (the 'home' method).只有当路由器到达默认路由(“home”方法)时,您才创建此 object。 but when you are looking at the '#/products/20' hash fragment and you hit the refresh button in your browser, the home method on your router does not execute.但是当您查看“#/products/20”hash 片段并点击浏览器中的刷新按钮时,路由器上的 home 方法不会执行。 only the showProduct route executes.只有 showProduct 路由执行。

this should be easy to fix, though.不过,这应该很容易解决。 you need to move the creation of "appView" outside of your router:您需要将“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});

Now the "window.App.appView" will always be created when the page loads up and executes your javascript, no matter what route is executed.现在“window.App.appView”将始终在页面加载并执行您的 javascript 时创建,无论执行什么路由。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM