0

I am using Bootstrap UI's accordion directive. This uses transclusion under the hood. I have some logic that needs repeated, so I am trying to create a directive that wraps the accordian, which also uses transclusion.

<div>
    <div accordion>
        <div accordion-group is-open="isOpen">
            <div accordion-heading>
                <span class="glyphicon" ng-class="{'glyphicon-minus-sign': isOpen, 'glyphicon-plus-sign': !isOpen}"></span>
                <strong>{{headerTitle}}</strong>
            </div>
            <div ng-transclude></div>
        </div>
    </div>
</div>

Here is the JavaScript:

application.directive('collapsePanel', ['baseUrl', function (baseUrl) {
    return {
        restrict: 'A',
        templateUrl: baseUrl + 'content/templates/collapse_panel.html',
        replace: true,
        transclude: true,
        scope: {
            headerTitle: '@'
        },
        controller: ['$scope', function ($scope) {
            $scope.isOpen = false;
        }]
    };
}]);

It should be as simple to use as:

<div collapse-panel header-title="Title">
    {{scopeVariable}}
</div>

Assuming scopeVariable is in my controller, I would think its value would appear. From what I can tell, the scope belongs to the collapse-panel rather than the outer scope. It is almost like having nested transclusion directives is causing my problem.

Is there a trick to nesting transclusions like this?

Travis Parks
  • 8,435
  • 12
  • 52
  • 85
  • you are mixing scopes here, which isn't going to work the way you expect. you are using an isolate scope `scope : {`, but then trying to use a non-islolate scope `$scope` within the controller. aside from that, you may need `transclude: 'element'` rather than `transclude: true`. – Claies Mar 25 '15 at 18:33
  • `transclude: true` - transclude the content of the directive. `transclude: 'element'` - transclude the whole element including any directives defined at lower priority. http://stackoverflow.com/a/18457319/2495283 – Claies Mar 25 '15 at 18:37
  • I need a scope to track whether the control is open and the title of the panel. I'm not sure how `true` vs `element` applies to my situation. – Travis Parks Mar 25 '15 at 18:47
  • Looks like someone else is asking the same thing: http://stackoverflow.com/questions/22296084/directives-isolated-scope-variables-are-undefined-if-it-is-wrapped-in-a-directi – Travis Parks Mar 25 '15 at 18:56
  • yes, you need *a* scope, but you can't use `scope` and `$scope` within the same directive. – Claies Mar 25 '15 at 19:13
  • Maybe I am wrong, but I am pretty sure `scope` just tells AngularJS how to build an isolate scope and `$scope` is the actual scope object that gets created, which is passed to the controller. – Travis Parks Mar 25 '15 at 19:19
  • not correct at all. `$scope` is a scope object inherited from `$rootScope`, `scope` is an isolated scope object. it's even defined in JSON object syntax. Unfortunately quite confusing; one of the reasons that scope is being replaced by ECMA6 features in Angular 2. Angular copies properties from `$scope` to `scope` based on the rules defined in the definition. – Claies Mar 25 '15 at 19:21

0 Answers0