Angular 2 - Dynamic JSON Data Routing

In Angular 2.0 stable, I have an application in which I have to define / config routes based on the JSON data that I get. I have no predefined routes. I get this data in the constructor of my bootstrap component.

How can i achieve this? Is it possible?

+4
source share
1 answer

The way I have achieved this is to load the routes before downloading the angular application. Thus, when the application starts, all dynamic routes already exist.

Therefore, you need to load all the routes in the main.ts file before the line platformBrowserDynamic().bootstrapModule(AppModule);.

main.ts, json .

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { environment } from './environments/environment';
import { AppModule } from './app/app.module';
import { IRoute, IRouteData } from './core/models/route';
import { getComponent } from './core/utils/type-component-mapper';

import { AppRoutes } from './app/app.routes';

export function main() {
    console.log('[main]')
    return platformBrowserDynamic()
        .bootstrapModule(AppModule)
        .catch(err => console.error(err));
}

switch (document.readyState) {
    case 'interactive':
    case 'complete':
        getRoutes();
        break;
    case 'loading':
    default:
        document.addEventListener('DOMContentLoaded', () => getRoutes());
}

function getRoutes() {
    // This is where you load the routes json from your api
    fetch(environment.apiUrl + '/api/routes/get').then((value: Response)  =>                         
    {
        return value.json();
    }).then((routes: IRoute[]) => {
        routes.forEach((o: IRoute) => {
            iterate(o);
        });

        // add each dynamic route to the angular route collection
        AppRoutes.unshift(routes[0]);

        // all dynamic routes have been added, start the angular app
        main();
    });
}

function iterate(route: IRoute) {
    var children = route.children;
    if (children) {
        Array.from(children).forEach((o: IRoute) => {
            iterate(o)
        });
    }

    var component = getComponent(route.data.type);
    if (component) {
            route.component = component;
    }
}

json, api, :

[{
    "path" : Shop,
    "data" : {
        "type" : ShopPage
    },
    "children" : [{
        "path" : Bread,
        "data" : {
            "type" : ProductPage
        }
    },
    {
        "path" : Milk,
        "data" : {
            "type" : ProductPage
        }
    }]
}]

Json IRoute IRouteData:

export interface IRoute {
    path: string;
    data: IRouteData;
    children?: IRoute[];
}

export interface IRouteData {
    type: string;
}

AppRoutes const, AppRoutes. :

export const AppRoutes: Routes = [
    {
        path: 'hardCodedWelcome',
        component: WelcomeComponent
    }
];

. , . get type-map-mapper, :

import { Router, Route } from '@angular/router';

import { Type } from '@angular/core';
import { PageTypes } from './page-types';
import { ShopComponent } from '../../app/Shop/shop.component';
import { ProductComponent } from '../../app/Product/Product.component';

export function getComponent(type: string): Type<any> {
    switch (type) {
        case PageTypes.Shop: {
            return ShopComponent;
        }
        case PageTypes.Product: {
            return ProductComponent;
        }
    }
}

, .

export const PageTypes = {
    Shop: 'ShopPage',
    Product: 'ProductPage',
};

angular. , . , config .

, , AOT . AOT, app.component, : router.resetConfig(allRoutes);, - , .

+2

Source: https://habr.com/ru/post/1657735/


All Articles