使路线对应于Bootstrap轮播中的幻灯片,并在幻灯片更改时更新该路线

时间:2016-06-23 23:44:25

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

我正在使用ui-bootstrap和ui-router。我希望有一个URL结构,允许我链接到轮播中的幻灯片,例如,

/carousel/123/slide/789

这将加载轮播“123”并显示幻灯片“789”作为活动幻灯片。

我还希望更新此网址以反映幻灯片显示的内容。

我尝试了一些更新路线的方法,虽然它按预期工作,但它没有完成工作,因为有些情况下它不会在逻辑上起作用。

我知道让控制器知道DOM并且使用JQuery就像下面的示例代码不是Angular方式,但我不认为这对我试图解决的问题很重要。 我被要求添加路线到这个应用程序,而不是实现最佳实践。 如果将事情转移到指令或以其他方式修复它将帮助我解决当前的问题,而不是所有人都是意思是,我想要它,否则它必须留一天。

我尝试的第一件事是没有激活加载的第一页的路线:

在我的控制器中,

jQuery($scope.data.carouselSelector).on('slide.bs.carousel', function () {
  var newRoute = $state.href($state.current, {photoId:currentPhoto.id});
  $location.path(newRoute);
}

在我的配置中,

.run(['$urlRouter', function ($urlRouter) {
    $rootScope.$on('$locationChangeSuccess', function(e, newUrl, oldUrl) {

      e.preventDefault();

      // This doesn't work because newUrl and oldUrl are the same when the app fires up at a route
      if (newUrl !== oldUrl) {
        $urlRouter.sync();
      } else {
        console.log('SKIP SYNCING');
      }

    });
    $urlRouter.listen();
  }]);

我尝试的第二件事是添加一个查询参数,指示应该跳过同步路由,因为已经发生了更改。

在我的控制器中,

jQuery($scope.data.carouselSelector).on('slide.bs.carousel', function () {
  var newRoute = $state.href($state.current, {photoId:currentPhoto.id});
  $location.path(newRoute + '?ok=1');
}

在我的配置中,

.run(['$urlRouter', function ($urlRouter) {
    $rootScope.$on('$locationChangeSuccess', function(e, newUrl, oldUrl) {

      e.preventDefault();

      // I also tried adding a query parameter when the slide changes after the carousel has been loaded. But there is no way of knowing why skipSync=1 is in the URL. A user could have bookmarked it or even just reloaded the poage for instances.
      if (newUrl.indexOf('skipSync=1') !== -1) {
        $urlRouter.sync();
      } else {
        console.log('SKIP SYNCING');
      }
    });
    $urlRouter.listen();
  }]);

为了使事情复杂化,旋转木马处于一个模态,我打开这样的颜色 -

在我的配置中,

.state("search.photo-view", {
  url: "/photo/:photoId",
  onEnter: ['$state', '$modal', function($state, $modal) {
      $modal.open({
        templateUrl: "photo-fullscreen.html",
        controller: "PhotoFullscreenController"
      }).result.finally(function() {
        $state.go('^');
      });
    }]
  })

在我看来,如果有一种方法可以从配置中知道模式是否打开,我可以假设它包含一个旋转木马并且已经显示我想要的幻灯片。

1 个答案:

答案 0 :(得分:0)

我最终在配置中跟踪是否与路径关联的模态已经打开,如果模态存在则忽略路径更改。注意当模态的关闭触发了promise的'finally'时,我将变量设置为null:

var myApp = angular.module("myApp", ["ui.router"]);
myApp.config(["$stateProvider", function($stateProvider) {

  var carouselModalInstance, personModalInstance;

  $stateProvider.state("home.photo-view", {
    url: "/photo/:photoId",
    onEnter: ['$rootScope', '$stateParams', '$state', '$modal', '$resource', function($rootScope, $stateParams, $state, $modal, $resource) {

      if (!carouselModalInstance) {
        carouselModalInstance = $modal.open({
          templateUrl: "photo-fullscreen.html",
          controller: "PhotoFullscreenController"
        }).result.finally(function() {
          carouselModalInstance = null;
          $state.go('^');
        });
      }
      }]
    })
}]);

在其他地方(在我的控制器中),当旋转木马中的幻灯片完成滑动时,我会在事件ui bootstrap发出时更新路线:

jQuery($scope.data.carouselSelector).on('slid.bs.carousel', function () {

    var currentPhoto = getSlideForIndex(getCurrentSlideIndex());

    if (currentPhoto) {
      onPhotoChanged(currentPhoto);

    }

    var newRoute = unescape($state.href($state.current, {photoId:currentPhoto.id}));
    $location.path(newRoute);

});