嵌套指令,没有模板,但在父指令中使用ng-repeat

时间:2016-02-17 12:03:37

标签: angularjs angularjs-ng-repeat directive angularjs-ng-transclude

我试着解释我的问题:

我有一个包含元素列表的自定义指令(此时元素是自定义指令,但我不知道它是否正确)。 对于每个元素,我需要取一些值并将值放在父指令中,其中我有两个不同的ng-repeat。 也许有人认为我应该在嵌套指令中使用这些值,并在父级中使用ng-transclude。但我不能,因为嵌套指令应该有两个不同的模板。 也许它不太清楚,所以我让你看看我的代码:

Index.html (我在哪里使用该指令)

<rh-portfolio>
    <rh-portfolio-image id="portfolio-item-six" url="images/portfolio/thumbnail/img-01.jpg" description="" category="construction"></rh-portfolio-image>
    <rh-portfolio-image id="portfolio-item-seven" url="images/portfolio/thumbnail/img-02.jpg" description="" category="construction"></rh-portfolio-image>
    <rh-portfolio-image id="portfolio-item-eight" url="images/portfolio/thumbnail/img-03.jpg" description="" category="construction"></rh-portfolio-image>
    <rh-portfolio-image id="portfolio-item-nine" url="images/portfolio/thumbnail/img-04.jpg" description="" category="construction"></rh-portfolio-image>
    <rh-portfolio-image id="portfolio-item-ten" url="images/portfolio/thumbnail/img-05.jpg" description="" category="construction"></rh-portfolio-image>
</rh-portfolio>

portofolio.js (其中包含父指令和嵌套指令)

.directive('rhPortfolio', function () {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: '/partial_views/directives/templates/portfolio.html',
        scope: {},
        controller: ['$scope', function ($scope) {
            var images = $scope.images = [];

            $scope.select = function (image) {
                angular.forEach(images, function (image) {
                    image.selected = false;
                });
                image.selected = true;
            };

            this.addImage = function (image) {
                if (image.length === 0) {
                    $scope.select(image);
                }
                images.push(image);
            };
        }]
    };
})
.directive('rhPortfolioImage', function () {
    return {
        restrict: 'E',
        replace: true,
        require: '^^rhPortfolio',
        link: function (scope, element, attrs, portfolioCtrl) {
            portfolioCtrl.addImage(scope);
        }
    };
});

最后,指令的模板

...
<div class="tab-content tg-img-border"><!--portfolio-item-one-->
    <div role="tabpanel" class="tab-pane fade in active" ng-repeat="image in images" id="{{ image.id }}">
        <figure><img src="{{ image.url }}" alt="{{ image.description }}"></figure>
    </div>
</div>
... <!-- Here in the middle, there is a lot of code that must not be replicated -->  
<div role="presentation" ng-repeat="image in images" class="active portfolio-item grid-item {{ image.category }}">
    <div class="product-box">
        <a href="#{{ image.id }}" aria-controls="{{ image.id }}" role="tab" data-toggle="tab">
            <figure><img src="{{ image.url }}" alt="{{ image.description }}"></figure>
            ...
        </a>
    </div>
</div>
...

如您所见,嵌套指令没有唯一的模板..所以我决定使用两个不同的ng-repeat。在两个ng-repeat之间,存在不应重复的代码,因此意味着,无论如何必须在父指令内。

无论如何,我的代码不起作用......我既不明白为什么.. perhpas因为尝试使用在父控制器中定义的“image”元素的属性,但它是从嵌套填充的指令。

修改 在这里你可以看到问题..在页面的底部,你应该看到投资组合,图像......但是有些东西不起作用: http://simonerh.altervista.org/_test/

在这里你可以看到没有Angularjs的版本(所以,我希望看到的): http://simonerh.altervista.org/

EDIT2 这是一个Plunker版本 http://plnkr.co/edit/nf2bVkNujtb69WRfs0I7?p=preview

任何人都可以帮助我吗? 感谢名单

1 个答案:

答案 0 :(得分:0)

你有三个问题。

  1. 您不会在指令rh-portfolio-image中传递参数。例如 ID 网址
  2. 您的指令rh-portfolio-image未调用,因为指令rh-portfolio具有属性replace:true
  3. 您不使用transclude:true。有关ng-transclude
  4. 的更多详细信息

    我要更改您的模板portfolio.html。请检查punker。它没有完成解决方案,但它向您展示了如何创建指令。

    &#13;
    &#13;
    var renovahaus = angular.module("renovahaus", [])
    .directive('rhPortfolio', function () {
            return {
                restrict: 'E',
                replace:true,
                transclude:true,
                template: '<section class="tg-main-section tg-haslayout bg-white">  <pre>images = {{images|json}}</pre><div  ng-transclude></div></section>',
                scope: {},
                controller: ['$scope', function ($scope) {
                    var images = $scope.images = [];
    
                    $scope.select = function (image) {
                        angular.forEach(images, function (image) {
                            image.selected = false;
                        });
                        image.selected = true;
                    };
    
                    this.addImage = function (image) {
                        if (image.length === 0) {
                            $scope.select(image);
                        }
                        images.push(image);
                    };
                }]
            };
        })
        .directive('rhPortfolioImage', function () {
            return {
                restrict: 'E',
                //replace: true,
                require: '^^rhPortfolio',
                scope: {id:"="},
                template:'<span>{{id}}</span>',
                link: function (scope, element, attrs, portfolioCtrl) {
                    console.log(1);
                    portfolioCtrl.addImage(scope);
                }
            };
        }) .directive('rhPortfolioIm', function () {
            return {
                restrict: 'E',
                scope: {id:"@"},
                require: '^rhPortfolio',
                template:'<span>{{id}}</span>',
                link: function (scope, element, attrs,portfolioCtrl) {
                    portfolioCtrl.addImage(scope);
                }
            };
        });
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <!DOCTYPE html>
    <html class="no-js" lang="">
    
    <head>
      <meta charset="utf-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <title>BootStrap HTML5 CSS3 Theme</title>
      <meta name="description" content="" />
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <link rel="apple-touch-icon" href="apple-touch-icon.png" />
      <script data-require="jquery@1.11.3" data-semver="1.11.3" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
      <link data-require="bootstrap@3.3.5" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
      <link data-require="bootstrap@3.3.5" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.5/cosmo/bootstrap.min.css" />
      <link data-require="bootstrap@3.3.5" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" />
      <script data-require="bootstrap@3.3.5" data-semver="3.3.5" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
      <script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
    
      <link rel="stylesheet" href="style.css" />
      <script src="app.js"></script>
      <script src="portfolio.js"></script>
    </head>
    
    <body class="home" ng-app="renovahaus">
      <rh-portfolio>
        <rh-portfolio-im id="'portfolio-item-six'"></rh-portfolio-im>
        <rh-portfolio-im id="'portfolio-item-seven'"></rh-portfolio-im>
      </rh-portfolio>
    </body>
    
    </html>
    &#13;
    &#13;
    &#13;

    P.S。标记<div ng-transclude></div>中包含指令rhPortfolioIm