Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 Multiple Slot Transclusion

Tags:

angular

As of RC 5 the following syntax worked just fine for multiple slot transclusion in Angular 2

This was the template component with a selector statement-card

<div class="statement-card bottom-right-shadow">
    <div class="row">
        <div class="col-xs-12">
            <div class="statement-card-title">
                <!-- title -->
                <ng-content select="statement-card-title"></ng-content>
            </div>
        </div>
    </div>
    <div class="row statement-card-body">
        <div class="col-md-4">
            <!-- statment summary -->
            <ng-content select="statement-card-summary"></ng-content>
        </div>
        <div class="col-md-4">
            <!-- payment amount -->
            <ng-content select="statement-card-addition"></ng-content>
        </div>
        <div class="col-md-4">
            <!-- payment method -->
            <ng-content select="statement-card-payment-method"></ng-content>
        </div>
    </div>
    <div class="row statement-card-footer">
        <div class="col-md-4 col-md-offset-8">
            <ng-content select="statement-card-interactions"></ng-content>
        </div>
    </div>
</div>

This was one of the components which filled in the template with data

<statement-card>
    <statement-card-title>
        <div class="schedule-statement-title">Payment schedule</div>
    </statement-card-title>
    <statement-card-summary>
        <h4 class="statement-card-section-title">Payment frequency:</h4>
        <div>
            {{frequency}}
        </div>
        <div>
            Next payment: {{payment?.scheduledDate | date:'MMMM dd, yyyy'}}
        </div>
    </statement-card-summary>
    <statement-card-addition>
        <h4 class="statement-card-section-title">Payment amount:</h4>
        <div class="addition-line"><span>Amount</span><span>{{payment?.amount}}</span></div>
        <div class="addition-line"><span>Sales tax</span><span>{{payment?.salesTax}}</span></div>
        <hr class="addition-seperator" />
        <div class="addition-total"><span>Total</span><span>{{getPaymentTotal()}}</span></div>
    </statement-card-addition>
    <statement-card-payment-method>
        <h4 class="statement-card-section-title">Payment method:</h4>
        <img src="images/bank.png" width="48" height="48" class="payment-method-icon" />
        <div class="payment-method-summary">
            <div>Bank</div>
            <div>Account ending in  ••••••••••1234</div>
        </div>
    </statement-card-payment-method>
    <statement-card-interactions>
        <div class="row">
            <div class="col-md-6">
                <a href="#" class="pull-right">MAKE A PAYMENT</a>
            </div>
            <div class="col-md-6">
                <a href="#" class="pull-right">VIEW PAYMENT SCHEDULE</a>
            </div>
        </div>
    </statement-card-interactions>
</statement-card>

In Angular 2 RC 5 and below you could specify an ng-content tag with a select attribute in a template component and then in a specific component directly create an html tag that matched the select attribute in the ng-content tag and it would transclude the children html content into the ng-content tag.

Now that I have upgraded to angular 2 it is throwing an error like this for all of the transclusion slots:

'statement-card-title' is not a known element: 1. If 'statement-card-title' is an Angular component, then verify that it is part of this module. 2. If 'statement-card-title' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schema' of this component to suppress this message. (" [ERROR ->] Payment schedule

Do I now have to make a separate component for all of the transclusion slots?? If not how do I fix my component so that angular recognizes this is multiple transclusion?

like image 891
tt9 Avatar asked Sep 26 '16 16:09

tt9


Video Answer


3 Answers

Another way of solving this is to update your selector to something like:

<ng-content select="[statement-card-title]"></ng-content>

And use it in your component as:

<statement-card>
    <div statement-card-title>
        <div class="schedule-statement-title">Payment schedule</div>
    </div>
    <div statement-card-summary>
        <h4 class="statement-card-section-title">Payment frequency:</h4>
        (...)
    </div>
    (...)
</statement-card>
like image 193
yorch Avatar answered Nov 06 '22 06:11

yorch


This is a known "issue".

You can fix it by passing

 schemas:   [ CUSTOM_ELEMENTS_SCHEMA ],    

to @NgModule(...) to explicitly tell Angular2 it should accept all tag names that fit the custom elements name scheme even when the components are not known to your current Angular2 module.

If you add the component with this selector to directives: [...] of the @NgModule(...) then Angular2 also won't complain anymore.

See also https://github.com/angular/angular/issues/11251 for more details.

like image 41
Günter Zöchbauer Avatar answered Nov 06 '22 06:11

Günter Zöchbauer


this problem in Angular 2 does not recognize the "statement-card-section-title" tag. "statement-card-section-title" is neither a directive nor a component. A quick way to get around this error is to add schema metadata property in your module, set value to NO_ERRORS_SCHEMA in your module file.

@NgModule({
  ...,
  schemas:      [ NO_ERRORS_SCHEMA ] // add this line
})
like image 25
rodolfocop Avatar answered Nov 06 '22 06:11

rodolfocop