如何在指令模板中使用控制器 $scope

how to use controller $scope in directive template

我正在尝试使用 Angular 实现带有自定义指示器的轮播 Bootstrap,轮播运行良好,但我无法自定义指示器。

var App = angular.module('App', ['ngAnimate', 'ui.bootstrap', 'ngTouch']);
App.controller('Carousel', function($scope, $http, $element){
    $scope.myInterval = 5000;
    $scope.noWrapSlides = false;
    var slides = $scope.slides = [];

    $scope.slides = [{"img":"images\/bg-slider1.jpg","name":"GIFTS","class":"pinkbg"},{"img":"images\/bg-slider2.jpg","name":"FASHION","class":"ltgreen"},{"img":"images\/bg-slider1.jpg","name":"ASTROLOGY","class":"voilet"},{"img":"images\/bg-slider2.jpg","name":"ORGANIC","class":"green"},{"img":"images\/bg-slider1.jpg","name":"SPORTS","class":"yellow"},{"img":"images\/bg-slider2.jpg","name":"APPLIANCES","class":"grey"}];
    $scope.getNameByIndex = function(index){
        return $scope.slides[index]['name'];
    }
});

angular.module("template/carousel/carousel.html", []).run(["$templateCache", "$http", function($templateCache, $http) {
  $templateCache.put("template/carousel/carousel.html",
    "<div ng-mouseenter=\"pause()\" ng-mouseleave=\"play()\" class=\"carousel\" ng-swipe-right=\"prev()\" ng-swipe-left=\"next()\">\n" +
    "    <ol class=\"carousel-indicators\" ng-show=\"slides.length > 1\">\n" +
    "        <li ng-repeat=\"slide in slides | orderBy:indexOfSlide track by $index\" ng-class=\"{active: isActive(slide)}\" ng-click=\"select(slide)\" class='{{slide.class}}'>{{slide.name}}</li>\n" +
    "    </ol>\n" +
    "    <div class=\"carousel-inner\" ng-transclude></div>\n" +
    "</div>\n" +
    "");
}]);

$scope.slides 有额外的属性,nameclass 需要放在指标中。我该怎么做?

Plunker

首先,这引起了我对为什么无法访问范围的兴趣。在对 GitHub 上可用的源代码进行详细分析后,我发现范围在库中被隔离。

Plukr Link

我在 plunkr 上修改了库。文件名:angular-bootstrap-modified.js

阅读下文了解详情。

请参阅来自 Git Hub 的以下代码块:

.directive('carousel', [function() {
  return {
    restrict: 'EA',
    transclude: true,
    replace: true,
    controller: 'CarouselController',
    controllerAs: 'carousel',
    require: 'carousel',
    templateUrl: function(element, attrs) {
      return attrs.templateUrl || 'template/carousel/carousel.html';
    },
    scope: {
      interval: '=',
      noTransition: '=',
      noPause: '=',
      noWrap: '&'
    }
  };
}])

为指令新创建的独立范围变量从其父范围继承以下数据。

{
   interval: '=',
   noTransition: '=',
   noPause: '=',
   noWrap: '&'
}

最后发现是库本身的限制。

所以我修改了库来实现解决方案。以下是我更改的内容

图书馆代码:

scope: {
         interval: '=',
         noTransition: '=',
         noPause: '=',
         noWrap: '&',
         slidesData : '=slides'
    }

并在 HTML 中:

<carousel interval="myInterval" no-wrap="noWrapSlides" slides="slides">

修改后,哇哦!现在指令隔离范围也继承了 slides 数据。甜!

可以找到关于 Angular 指令的信息 - here

接下来调整模板代码:我所做的就是将 slides 引用更改为 slideData

angular.module("template/carousel/carousel.html", []).run(["$templateCache", "$http", function($templateCache, $http) {
  $templateCache.put("template/carousel/carousel.html",
    "<div ng-mouseenter=\"pause()\" ng-mouseleave=\"play()\" class=\"carousel\" ng-swipe-right=\"prev()\" ng-swipe-left=\"next()\">\n" +
    "    <ol class=\"carousel-indicators\" ng-show=\"slidesData.length > 1\">\n" +
    "        <li ng-repeat=\"slide in slidesData | orderBy:indexOfSlide track by $index\" ng-class=\"{active: isActive(slide)}\" ng-click=\"select(slide)\" class='{{slide.class}}'>{{slide.name}} - {{$index}}</li>\n" +
    "    </ol>\n" +
    "    <div class=\"carousel-inner\" ng-transclude></div>\n" +
    "</div>\n" +
    "");
}]);

很好,现在我可以在 <ol></ol> 标签元素上看到 nameclass 呈现。

但是现在 <li> 上没有切换动画。下面是比较范围而不是索引的例程(我不知道为什么?)

$scope.isActive = function(slide) {
     return self.currentSlide === slide;
};

我通过观察调试器控制台上的表达式弄明白了

最后的话:

如果你想以某种方式实现它..你必须修改库源本身。如果您想要自定义滑块或使用 Angular Bootstrap 库提供的滑块,我建议您查看其他滑块。


希望以上信息能解释限制。编码愉快!


还有Git集线器问题logged


关于这个问题的更新

根据Git集线器问题更新

,轮播自定义将在未来的版本中实现