Angular,以浏览用户的模式显示内容,但在新用户的新页面上显示内容

时间:2014-12-02 20:41:20

标签: angularjs angular-ui-bootstrap angular-ui-router

我正在尝试向已在我网站浏览中的用户显示相同的内容(使用相同的网址),但是在新用户的新页面上显示。

例如,用户在树冠上的旅程:

转到https://canopy.co/,然后点击链接。内容以模式加载,其网址已更新为https://canopy.co/products/12309 但是直接转到https://canopy.co/products/12309并将其加载到自己的视图中,没有模态。

我怎么能用角度做这个?我已尝试使用ui-router和多个视图加载一些东西但最终会渲染两次。

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

这可能有几种方法。这是我的。

概要

当状态发生变化时,我们想要检查我们是否可以在当前视图中为模式内的内容提​​供服务,而不是完全替换当前视图。我们将在路由配置中定义 - 可以托管模态的视图将具有modalMaster标志,并且可以在模态中显示的视图将具有modalSlave标记。

我们将使用ui.router的{​​{1}}事件拦截状态更改,并在必要时取消它们,这是我们打开模式的地方。

挑战

  • 如果有一个
  • ,我们需要保持对模态状态的了解
  • 防止状态更改也会阻止URL更改,因此我们需要手动执行此操作
  • 使用浏览器后退按钮应该关闭模式并将我们带回到其下方的状态。

代码

请注意,所有代码都在coffeescript和jade中,我发现它更整洁。如果您需要转录,请使用js2coffee.org

路由器配置:

$stateChangeStart

最后一行很重要,因为它允许我们停止更新视图的URL更改。

状态和URL事件侦听器

.config ($stateProvider, $urlRouterProvider)->

  # Add details on which templates can open models containing which other 
  # templates.
  $stateProvider.state 'shop',
    url: '/'
    templateUrl: 'shop.html'
    modalMaster: true

  $stateProvider.state 'item',
    url: '/item/{id}'
    templateUrl: 'item.html'
    modalSlave: true

  $urlRouterProvider.otherwise('/');

  # Enable handling of url changes ourselves.
  $urlRouterProvider.deferIntercept()

评论应该解释大部分内容。在实践中,你可能需要比这里更多的东西 - 例如,你应该确保正确处理从模态内部点击链接的情况,但这应该让你开始。

当然,我已经做了一个能够展示这个解决方案 here 的插件,但请确保您使用“在单独窗口中启动预览”功能,以确保一切正常工作。

结果

.run ($rootScope, $state, $modal, $location, $urlRouter, $timeout)-> # set some flags for use later. modalInstance = toStatePrevented = entering = null # Intercept state changes - if we're in a modal master and we're going to a # modal slave, open a modal containing the slave state instead. $rootScope.$on '$stateChangeStart', (event, toState, toParams, fromState)-> if fromState.modalMaster and toState.modalSlave event.preventDefault() # set a property to show which state is currently in the modal $state.current.inModal = toState entering = true # for url handling $timeout -> # change url manually $location.path($state.href(toState, toParams), false) , 0 # the 0 timeout makes sure the preventDefault doesn't stop url # change # open a modal containing the new state, you can merge this with # modal specific properties like "resolve" etc. if you want them modalInstance = $modal.open(toState) # clear our flags when the modal closes - this only uses dismiss so we # only need "catch" right now. modalInstance.result.catch(()-> modalInstance = toStatePrevented = $state.current.inModal = entering = null $state.go(fromState) ) $rootScope.$on '$locationChangeSuccess', (event, toUrl, fromUrl)-> event.preventDefault() # if there is nothing in a modal, just handle as normal if !$state.current.inModal? then $urlRouter.sync() # dismiss modal if url changes and modal is visible else if not entering and modalInstance? then modalInstance.dismiss() # if we are opening a modal, set a flag so that next time the url changes # we will dismiss it. else entering = false 导航到shop会打开一个模式,但通过网址直接导航到item会自动打开该项item