【问题标题】:Back button doesn't re-trigger backbone app后退按钮不会重新触发骨干应用
【发布时间】:2014-10-17 20:04:37
【问题描述】:

我在我的 Backbone Marionette 应用程序中遇到了一个奇怪的场景。如果用户单击 facebook/twitter 链接,然后单击浏览器后退按钮,而不是重新加载我的应用程序,它只会显示 json,就好像我去了 example.com/posts.json 而不是 example.com/posts。如果用户手动重新加载页面,它可以正常加载,但用户看到 json 会很混乱。

如果我在example.com/posts 然后手动导航到说gmail.com 并单击返回按钮它工作正常。似乎是在单击我的应用程序中的链接时出现了这种情况。

知道如何在单击返回按钮导航回到我的应用程序时“强制”重新加载 Backbone 应用程序吗?

编辑:

添加我的 Rails 控制器 - 它正在点击索引。但是当点击后退按钮时,它似乎触发了 json 与 html(尽管在同一页面上刷新会导致它点击正确的 html):

class SurveysController < ApplicationController    
  # GET /surveys
  # GET /surveys.json
  def index
    if cookies[:sample_user_id] && !User.find(cookies[:sample_user_id]).admin?
      if !cookies[:sample_appuser_token] 
        appuser = Appuser.create
        sign_in_appuser appuser
      else
        appuser = current_appuser
      end
      @surveys = User.find(cookies[:sample_user_id]).surveys.includes([:responses => [:choices], :questions => [:answers]])
    else
      if !cookies[:sample_appuser_token] 
        appuser = Appuser.create
        sign_in_appuser appuser
      else
        appuser = current_appuser
      end
      @surveys = Survey.where(status: "Submitted")
      if cookies[:sample_user_id]
        User.find(cookies[:sample_user_id]).surveys.each do |survey|
          @surveys << survey
        end
      end
    end
  end

还有 index.html.erb 视图:

<div id="wrap">
  <div id="header-region"></div>
  <div id="main-region"></div>
  <div id="push"></div>
</div>
<div id="footer-region"></div>
<div id="dialog-region"></div>
<%= debug(params) if Rails.env.development? %>

<%= javascript_tag do %>
  $(function() {
    Sample.start({
      environment: "<%= Rails.env %>"
    });
  });
<% end %>

SurveysRouter:

@Sample.module "SurveysApp", (SurveysApp, App, Backbone, Marionette, $, _) ->

  class SurveysApp.Router extends Marionette.AppRouter
    appRoutes:
      ""            : "list"
      ":id"         : "show"
      ":id/take": "take"

  API =
    list: ->
      if $.cookie('sample_user_email') != null
        new SurveysApp.List.Controller
      else
        window.location = "/signin"

    show: (id) ->
      window.fragment = Backbone.history.fragment
      if $.cookie('sample_user_email') != null
        new SurveysApp.Show.Controller
          id: id
      else
        console.log Backbone.history.fragment
        window.location = "/signin" + "#" + window.fragment

    take: (id, survey) ->
      new SurveysApp.Take.Controller 
        id: id 
        survey: survey

    newSurvey: (surveys, survey) ->
      if $.cookie('sample_user_email') != null
        new SurveysApp.New.Controller 
          surveys: surveys
          survey: survey
      else
        window.location = "/signin"

  App.vent.on "survey:clicked", (survey) ->
    App.navigate "/" + survey.id
    API.show survey.id

  App.vent.on "new:survey", (surveys, survey) ->
    API.newSurvey surveys, survey

  App.vent.on "take:survey:button:clicked", (survey) ->
    App.navigate "/" + survey.id + "/take"
    API.take survey.id, survey

  App.vent.on "survey:list", ->
    App.navigate "/"
    API.list()

  App.addInitializer ->
    new SurveysApp.Router
      controller: API

列表控制器:

@Sample.module "SurveysApp.List", (List, App, Backbone, Marionette, $, _) ->

  class List.Controller extends App.Controllers.Application

    initialize: ->
        surveys = App.request "survey:entities"

        App.execute "when:fetched", surveys, =>
            @layout = @getLayoutView()

            @listenTo @layout, "show", =>
          @surveyRegion surveys
          @bannerRegion surveys

        @show @layout
        App.request "header:footer"

    surveyRegion: (surveys) ->
      surveyView = @getSurveyView surveys

      @listenTo surveyView, "childview:survey:clicked", (args) ->
        if args.model.get('status') == "Draft"
          App.vent.trigger "new:survey", surveys, args.model
        else
            App.vent.trigger "survey:clicked", args.model


      @listenTo surveyView, "childview:take:survey:button:clicked", (child, args) ->
        survey = args.model 
        survey.set(preview: true)
        App.vent.trigger "take:survey:button:clicked", survey

      @show surveyView, region: @layout.surveyRegion

    getLayoutView: ->
      new List.Layout

    getSurveyView: (surveys) ->
      new List.Surveys
        collection: surveys

    bannerRegion: (surveys) ->
      bannerView = @getBannerView surveys

      @listenTo bannerView, "new:survey:clicked", ->
        App.vent.trigger "new:survey", surveys

      @show bannerView, region: @layout.bannerRegion

    getBannerView: (surveys) ->
      new List.Banner
        collection: surveys

以及链接所在的页脚模板:

<div class="container">
    <div class="row">
      <div class="col-sm-6 align-center">
        <a href="/privacy" id="footer-privacy-link">Privacy</a>
        <a href="/contact">Contact us</a>
        <div>©2014 Sample, LLC</div>
      </div>
      <div class="col-sm-4 align-center">
        <a class="facebook" href="https://www.facebook.com/sample"><i class="fa fa-facebook"></i></a>
        <a class="twitter" href="https://twitter.com/sample"><i class="fa fa-twitter"></i></a>
        <a class="email-link" href="/contact"><i class="fa fa-envelope"></i></a>
      </div>
    </div>
</div>

【问题讨论】:

  • 查看一些有问题的代码会很有帮助。

标签: javascript jquery ruby-on-rails backbone.js marionette


【解决方案1】:

您所描述的内容听起来像是 example.com/posts.json 已作为条目添加到浏览器的历史记录中。但是,AJAX 调用通常不会添加到历史记录中,因此您的代码中似乎必须有错误的 router.navigatewindow.location = 行或类似的东西。但是,如果没有看到相关代码,就无法确定。

【讨论】:

  • 我添加了一堆代码,但仔细查看它并没有真正弹出。不过你说的很有道理,我也会继续仔细研究它...... :)
  • 是的,我在您提供的代码中也没有发现任何明显错误。为了便于调试,您可能想做的一件事是打开 Backbone 的副本并找到 Backbone.historynavigate 方法(我的副本中的第 1469 行,但您的行 # 可能会有所不同),然后添加 console.trace()debugger 一行,以便您可以在代码调用它时进行判断。如果您的问题是错误的导航线,那应该可以帮助您找到它(如果不是,至少您会知道寻找window.location = 或一些手动历史操作代码)。
猜你喜欢
  • 1970-01-01
  • 2012-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-30
相关资源
最近更新 更多