angularjsangularjs-directiveangularjs-ng-transclude

How to define composable components in AngularJS


In AngularJS (1.x), how can we create a reusable widget (component) that has insertion points (slots) for other widgets (components)?

Imagine we have a component/directive called "verticalsplitter". It's purpose is to divide the screen area into a "top" and "bottom" area (perhaps allowing user resizing, collapsing, etc).

Now imagine we have a bunch of other rich components e.g. a richtextview, a treeview, a videoplayer and a gridview.

One page/view 1 I want a verticalsplitter with a richtextview on top and treeview on bottom. On page/view 2 I want a verticalsplitter with a videoplayer on top and a gridview on bottom.

Page 1

<html>
<body>
    <verticalsplitter>
        <top ng-initialSize="30%">
            <richtextview />
        </top>
        <bottom ng-initialSize="70%">
            <treeview  />
        </bottom>
    </verticalsplitter>
</body>
</html>

Page 2

<html>
<body>
    <verticalsplitter ng-locked="true">
        <top>
            <videoplayer />
        </top>
        <bottom>
            <gridview  />
        </bottom>
    </verticalsplitter>
</body>
</html>

How can I achieve this? If it's not possible with components (and I need to use directives for transclude) then that's OK.


Solution

  • Components can transclude. It is clearly stated so in the AngularJS Developers Guide for Components:

    app.component("verticlesplitter", {
        transclude: {
            'topPart': 'top',
            'bottomPart': 'bottom'
        },
        template: `
              <div style="border: 1px solid black;">
                  <div class="top" ng-transclude="topPart"></div>
                  <div>Something in the middle</div>
                  <div class="bottom" ng-transclude="bottomPart"></div>
              </div>
        `
    });
    

    For more information, see