Migrating host and ComponentResolver from AngularDart 4 to 5

Issue

I’m busy migrating a large Angular4 application (that was just migrated from Angular2) to Angular5.

In several places in the application, we make use of a directive to tag a div or other html element which then gets generated inside that component, in this case the contentItem directive is used to indicate that the div should be generated in the center of the layout whereas the footerItem indicated that the div should be generated at the bottom of the page layout.

<standard-layout
        (print)="handlePrintReport(\$event)"
        [hideScrollbars]="true">
        <div class="content-main-1" *contentItem>
            ...
        </div>
        <div class="content-main-2" *contentItem>
            ...
        </div>
        <div class="something-else" *footerItem>
            ...
        <div>
</standard-layout>

Inside StandardLayout,

<div 
    class="content-scroller" 
    [class.margin-auto]="contentScrollerMarginAuto"
    [class.overflow-hidden]="hideScrollbars">
    <template ngFor let-item [ngForOf]="contentItems [ngForTrackBy]="trackByFun">
        <template [ngTemplateOutlet]="item.template"></template>
    </template>
</div>

and

@ContentChildren(ContentItemDirective)
List<ContentItemDirective> contentItems;

@ContentChildren(ContentItemFooterDirective)
List<ContentItemFooterDirective> contentItemFooters;

In my ContentItemDirective, ComponentResolver no longer compiles, is there a drop-in replacement for it or do i require major changes to make this work in Angular5?

@Directive(selector: "[contentItem]")
class ContentItemDirective implements AfterContentInit {

    int id = IdProvider.generateIntIndex();

    final ViewContainerRef vcRef;
    final TemplateRef template;
    final ComponentResolver componentResolver;

    ContentItemDirective(this.vcRef, this.template, this.componentResolver);

    ComponentRef componentRef;

    @override
    ngAfterContentInit() async {
        final componentFactory =
        await componentResolver.resolveComponent(ContentItem);
        componentRef = vcRef.createComponent(componentFactory);
        (componentRef.instance as ContentItem)
            ..template = template;
    }
}

Then in my component factory, host no longer compiles, i guess i can just move that css-class injection into StandardLayout or is there an Angular5 way of doing this?

@Component(
    selector: "content-item",
    template: "",
    host: const {
        "[class.content-item]": "true",
    }
)
class ContentItem {

    int id = IdProvider.generateIntIndex();

    TemplateRef template;
}

TLDR, how do i migrate ComponentResolver and the host property inside @Component annotations.

Solution

host attributes on the Component change to @HostBindings or @HostListener annotations. In this case:

@HostBinding('class.content-item')
static const bool contentItemClass = true;

For the resolver you need to import the factory itself. Import the template.dart file for the ContentItem component. So if that file is content_item.dart you would import content_item.template.dart.

Then just use the type ContentItemNgFactory instead of doing the lookup using the type.

Answered By – Ted Sander

Answer Checked By – Mildred Charles (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *