Dynamic components for single-page applications (non-routing jumps)

Posted by doucie on Mon, 27 May 2019 21:12:48 +0200

Another approach is to apply angular single page to realize non-routing single page Jump by dynamically generating component method and cooperating with tabView component of primeNG UI Library

Dynamic Component Loader

Templates for components will not always be fixed. Applications may need to load some new components during runtime.

This case shows you how to use it. ComponentFactoryResolver To add components dynamically.

Following is a detailed description of how this case implements the component loading described in the title to achieve non-routing jumps (key red, attached) github/SubinY)

Management module

module.module.ts

...
@NgModule({
    imports: [
        ...
    ],
    declarations: [
        ...
        HeaderTopComponent,
        NavigationMenuComponent,
        ...ENTRY_COMPONENTS
    ],
    entryComponents: [
        ...ENTRY_COMPONENTS  //Components compiled on the client side are written here, which is traditionally referred to as lazy loading pages.
    ],
    providers: [
        TabViewResponseService
    ]
})
export class ModulesModule {
}

module.html

<div id="main-header">
    <header-top [widthSpread]="widthSpread" (widthChange)="widthChange($event)" (gotoPerson)="navPerson($event)"
                (headerHome)="headerHome($event)" (selectSubMenu)="changeSubMenu($event)"
                (personalCenter)="menuClickHandler($event)" (gotoYujing)="menuClickHandler($event)"></header-top>
    <app-navigation-menu [widthSpread]="widthSpread" [menuData]="navigateInfo"
                         (menuClickHandler)="menuClickHandler($event)"></app-navigation-menu>
</div>
<!--Routing page-->
<!--<router-outlet></router-outlet>-->
<div id="main-con" [ngStyle]="setContentStyle()">
    <div class="tab-view">
        <ui-tabview #tabview [tabs]="tabs" [activeIndex]="tabActiveIndex"
                    (tabClose)="handlerTabClose($event)" (tabChange)="handleTabChange($event)"></ui-tabview>
    </div>
</div>

In the past, it used to output pages through router-outlet, but now without routing control, it becomes a component encapsulating a layer of ui-tabview components installed in primeNG instead of routing output as shown above.

module.component.ts

...

@Component({
    ...
})
export class ModulesComponent implements OnInit, AfterViewInit {
    ...

    constructor(
        public tabViewService: TabViewService,
        public tabViewResponseService: TabViewResponseService) {
    }

    ngOnInit(): void {
        this.tabsComponent = this.tabViewService.getTabs();
        this.tabs.push(this.tabsComponent[0]);
        this.navigateInfo = navigateInfo;
    }

    /**
     * Menu Click Processing Events
     * @param $event
     */
    menuClickHandler($event) {
        let isOpen = false;
        this.tabs.forEach((tab, index) => {
            if (tab.data.name === $event.name) {
                this.tabActiveIndex = index;
                isOpen = true;
            }
        });
        if (!isOpen) {
            this.tabsComponent.forEach((tab, index) => {
                if (tab.data.name === $event.name) {
                    let selectedTab = this.tabview.findSelectedTab();
                    if (selectedTab) {
                        selectedTab.selected = false;
                    }
                    this.tabs.push(tab);
                    setTimeout(() => {
                        this.tabActiveIndex = this.tabs.length - 1;
                    }, 100)
                }
            });
            setTimeout(() => {
                this.tabViewResponseService.openTabNav(this.uiTabView.el.nativeElement);
            })
        }
    }

    /**
     * tab Turn off trigger events
     * @param $event
     */
    handlerTabClose($event) {
        let index = $event.index;
        this.tabs.splice(index, 1);

        this.tabViewResponseService.closeTabNav(this.uiTabView.el.nativeElement);
    }

    handleTabChange($event) {

    }

}

menuClickHandler and handler TabClose are two ways to control the addition and deletion of component arrays to see the tabview component of primeNG. The tabViewResponseService is used to dynamically calculate the maximum width of the page to control the width of the tab, and the style is controlled by some variables of scss. github/SubinY Go to see.

EntryComponents.ts

/*Order management*/
import { OrderManageComponent } from "./order-manage/order-manage.component";

/*Inventory management*/
import { WarehouseEntryManageComponent } from './warehouse-manage/page/warehouse-entry-manage/warehouse-entry-manage.component';
import { WarehouseLeaveManageComponent } from './warehouse-manage/page/warehouse-leave-manage/warehouse-leave-manage.component';
import { WarehouseCheckComponent } from './warehouse-manage/page/warehouse-check/warehouse-check.component';
import { WarehouseInfoComponent } from './warehouse-manage/page/warehouse-info/warehouse-info.component';
import { WarehouseAbnormalComponent } from './warehouse-manage/page/warehouse-abnormal/warehouse-abnormal.component';
import { WarehouseAreaAdjustmentComponent } from "./warehouse-manage/page/warehouse-area-adjustment/warehouse-area-adjustment.component";

export const ENTRY_COMPONENTS = [
    // The first page must be written in the first place, wherever other components are written.
    OrderManageComponent,
    WarehouseEntryManageComponent,
    WarehouseLeaveManageComponent,
    WarehouseCheckComponent,
    WarehouseInfoComponent,
    WarehouseAbnormalComponent,
    WarehouseAreaAdjustmentComponent,
]

Since a page must be displayed after login when module is initialized, the page component to be displayed must be placed in the first place, which is the first array set by module. component. TS life cycle.

 

TabView (Core of Dynamic Components)

tabview.html

<!--ui-tabview-->
<div class="tab-view">
    <p-tabView #tabRef  [activeIndex]="activeIndex" (onChange)="handleChange($event)" (onClose)="handleClose($event)">
        <p-tabPanel *ngFor="let tab of tabs;let i=index;" header="{{tab.data.name}}" selected="tab.data.selected"  [closable]="true" (click)="tabPanelClick(i)">
            <ui-tab-panel [tabItem]="tab"></ui-tab-panel>
        </p-tabPanel>
    </p-tabView>
    <div id="contextMenu">
        <p-menu [model]="items"></p-menu>
    </div>
</div>

This is the structure of primeNG, where ui-tab-panel is the page we want to display, tabs

Topics: github angular