0

I try to explain my problem:

I have a custom directive that contains a list of elements (in this moment the elements are custom directives, but I don't know if it is correct). For each element, I need to take some values and put the values inside the parent directive, where I have two different ng-repeat. Perhaps someone is thinking that I should use those values inside the nested directive and use ng-transclude in the parent. But I can't, because nested directive should have two different templates. Perhaps it's not clear, so I let you see my code:

Index.html(where I use the directive)

<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 (where there the parent and nested directives are)

.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);
        }
    };
});

And in the end, the template of the directive

...
<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>
...

As you can see, the nested directive would not have a unique template.. so I decided to use two different ng-repeat. In between the two ng-repeat, there is code that should not be repeated, so It means, that in any case must be inside the parent directive.

In anyway, my code does not work... I neither understand why.. perhpas because try to use the attribute of the "image" element that is defined in the controller of the parent, but it is filled from the nested directive.

EDIT Here you can see the problem.. In the bottom of the page, you should see the portfolio, with the images... but something does not work: http://simonerh.altervista.org/_test/

Here you can see the versione without Angularjs (so, what I expect to see): http://simonerh.altervista.org/

EDIT2 Here a Plunker version http://plnkr.co/edit/nf2bVkNujtb69WRfs0I7?p=preview

Can anyone help me? thanx

Simone
  • 2,304
  • 6
  • 30
  • 79
  • *"does not work"* is not a proper problem statement that gives anyone any real troubleshooting information to work from. That could mean anything from blank page to a minor detail. Update question with all relevant debugging details and a demo would really help also – charlietfl Feb 17 '16 at 12:58
  • It's difficult to explain.. I cannot see the images... From "developer tools" of Chrome I just see this error: `Failed to load resource: the server responded with a status of 404 (Not Found)` `http://localhost:2060/%7B%7B%20image.url%20%7D%7D` where `image.url` is from angular as you can see from template of directive – Simone Feb 17 '16 at 13:39
  • Wait, I try to publish the site so you can see the effect of my directive.. Howevere I think the way i thought the directive is totally wrong – Simone Feb 17 '16 at 13:40
  • A simple demo in [plunker](http://plnkr.co/edit/?p=catalogue) would be better if you want people to be able to help fork code changes – charlietfl Feb 17 '16 at 13:42
  • I edited my question.. I put a link where you can see directly the error on website i am doing. In the meanwhile, I'll try to do a demo on plunker. – Simone Feb 17 '16 at 14:06
  • @charlietfl, I have done a demo in plunker: http://plnkr.co/edit/nf2bVkNujtb69WRfs0I7?p=preview – Simone Feb 17 '16 at 14:33

1 Answers1

1

You have three problem.

  1. You do not pass parameters in the directive rh-portfolio-image. Such as id, an URL, etc.
  2. Your directive rh-portfolio-image do not invoke, because directive rh-portfolio has property replace:true.
  3. You do not use transclude:true. More detail about ng-transclude.

I'm change your template portfolio.html. Please check punker. It's not finish solution, but it show you, how create directive.

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);
            }
        };
    });
<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>

P.S. In tag <div ng-transclude></div> contain directive rhPortfolioIm.

Stepan Kasyanenko
  • 3,176
  • 1
  • 15
  • 23