【问题标题】:Controller 'uibCarousel', required by directive 'uibSlide', can't be found when wrapping包装时找不到指令“uibSlide”所需的控制器“uibCarousel”
【发布时间】:2015-10-16 13:33:00
【问题描述】:

我有一个包装该轮播指令的指令。当我替换幻灯片对象时,它会出现一个错误,提示“控制器'uibCarousel',指令'uibSlide'需要,在包装时找不到。”

我设法在 plunkr 中复制了它。我添加了一个简单的指令如下:

angular.module('ui.bootstrap.demo').directive('mydir', ['$compile',function($compile){
  function link(scope, element, attrs) {
    scope.$watch('slides', function (value) {
        var template = '<uib-carousel interval="myInterval" no-wrap="noWrapSlides">' +
        '<uib-slide ng-repeat="slide in slides" active="slide.active">' +
          '<img ng-src="{{slide.image}}" style="margin:auto;">' +
          '<div class="carousel-caption">' +
            '<h4>Slide {{$index}}</h4>' +
            '<p>{{slide.text}}</p>' +
          '</div>' +
        '</uib-slide>' +
      '</uib-carousel>;';
        element.empty();
        element.html(template);
        $compile(element.contents())(scope);
    });
  }
  return {
            link: link,
            restrict: 'E'
        };
}]);

我还添加了这个功能来替换幻灯片:

  $scope.createNewSlide = function(){
    $scope.slides = [];
    var newWidth = 600 + $scope.slides.length + 1;
    $scope.slides.push({
      image: '//placekitten.com/' + newWidth + '/300',
      text: ['More','Extra','Lots of','Surplus'][slides.length % 4] + ' ' +
        ['Cats', 'Kittys', 'Felines', 'Cutes'][slides.length % 4]
    });
  };

如果您点击替换幻灯片按钮,轮播仍然会出现,但您的控制台中会显示错误。 http://plnkr.co/edit/IGyaWwXGUa8n2LykMkmV?p=preview

当我替换幻灯片对象时,我是否在做不应该做的事情?

编辑:我注意到的一件事是删除 ng-repeat 指令不会导致此问题。另一个观察结果是,Angular 实际上编译了所有旧的 DOM 元素,这些元素从上次编译指令时被删除。我第一次注意到当它通过 uibSlide 寻找所需的控制器时,uibSlide 的元素实际上在 DOM 上。当我通过单击按钮添加新数组时,正在寻找控制器的第一个 uibSlide 位于已从 DOM 中删除的元素上。

【问题讨论】:

    标签: javascript angularjs angularjs-directive angular-ui angular-ui-bootstrap


    【解决方案1】:

    我想出了如何摆脱阻止 Angular 重新编译当前已删除的 DOM 元素的错误。

    我更改了链接器函数以保存子范围。当幻灯片数组发生变化时,我会自己销毁它,然后创建一个新的。

      function link(scope, element, attrs) {
        var childScope
        scope.$watch('slides', function (value) {
            var template = '<uib-carousel interval="myInterval" no-wrap="noWrapSlides">' +
            '<uib-slide ng-repeat="slide in slides" active="slide.active">' +
              '<img ng-src="{{slide.image}}" style="margin:auto;">' +
              '<div class="carousel-caption">' +
                '<h4>Slide {{$index}}</h4>' +
                '<p>{{slide.text}}</p>' +
              '</div>' +
            '</uib-slide>' +
          '</uib-carousel>;';
            element.empty();
            if(childScope)
              childScope.$destroy();
            childScope = scope.$new();
            element.html(template);
            $compile(element.contents())(childScope);
        });
      }
    

    http://plnkr.co/edit/g7wN2LSgbT4s7mULAzoJ?p=preview

    【讨论】:

    • 我发现这个页面详细说明了范围问题roubenmeschian.com/rubo/?p=51
    • 完全救了我。您知道如何将templateUrl 传递给template 而不是在其中声明完整的模板吗?
    【解决方案2】:

    从@Animal2 答案开始,我能够解决问题并通过$templateCache 导入模板槽

    function bannerDirective($compile, $http, $templateCache, $parse) {
    
        function link(scope, element, iAttrs) {
          var childScope
          scope.$watch('slides', function () {
            var template = $parse(iAttrs.data)(scope);
            $http.get('app/myBanner.html', {cache: $templateCache})
              .success(function(tplContent){
                element.replaceWith($compile(tplContent)(scope));
            });
              element.empty();
            if(childScope)
              childScope.$destroy();
            childScope = scope.$new();
            element.html(template);
            $compile(element.contents())(childScope);
          });
        }
    
          var directive = {
              restrict: 'E',
              controller: 'BannerController',
              controllerAs: 'bannerCtrl',
              bindToController: true,
              link: link
          };
    
          return directive;
      }
    

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2014-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-31
      相关资源
      最近更新 更多