Angular 2-从JSON数据动态路由 [英] Angular 2 - Dynamic routing from JSON data

查看:155
本文介绍了Angular 2-从JSON数据动态路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Angular 2.0稳定版中,我有一个应用程序,必须在其中基于接收到的JSON数据定义/配置路由.我没有任何预定义的路由.我正在引导程序组件的构造函数中获取此数据.

In Angular 2.0 stable, I have a application in which I have to define/config routes based on JSON data I receive. I don't have any predefined routes.I am getting this data in the constructor of my bootstrap component.

我该如何实现?有可能吗?

How can i achieve that? Is it possible?

推荐答案

我实现此目标的方法是在引导角度应用程序之前加载路由.这样,当应用程序启动时,所有动态路由都已经存在.

The way that I achieved this was to load the routes before bootstrapping the angular app. This way when the app starts all the dynamic routes are already there.

因此,您必须在 platformBrowserDynamic().bootstrapModule(AppModule); 行之前加载main.ts文件中的所有路由.

So you have to load all the routes in the main.ts file before the platformBrowserDynamic().bootstrapModule(AppModule); line.

这是main.ts文件的示例,其中的路由作为json提取并在引导之前加载.

Here is an example of the main.ts file where the routes are fetched as a json and loaded before bootstrapping.

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;
    }
}

在此示例中,从api返回的路由json将采用以下形式:

In this example the routes json which is returned from the api would be in this form:

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

此Json数据被解析为IRoute和IRouteData类型:

This Json data is parsed into the IRoute and IRouteData types:

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

export interface IRouteData {
    type: string;
}

导出AppRoutes常量也很重要,以便可以将新的动态路由推送到AppRoutes集合.看起来像这样:

It is also important that you export your AppRoutes const, so that you can push the new dynamic routes to your AppRoutes collection. It would look something like this:

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

您还需要为每个路线添加正确的组件.在这种情况下,我对数据类型属性进行了切换以获取正确的组件.这就是为什么我从看起来像这样的type-component-mapper文件中导入get component函数的原因:

You also need to add the correct component for each route. In this case, I do a switch on the data type property to get the correct component. This is why I import the get component function from the type-component-mapper file which looks like this:

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;
        }
    }
}

这里的页面类型只是页面类型的简单列表,因此我不必使用魔术字符串.

Page types here is just a simple list of page types so I do not have to use magic strings.

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

应用启动时,所有动态路线都将存在于路线集合中,并且可以通过角度正常解析.这将增加一些启动时间到应用程序,具体取决于有多少条路由.但是一旦应用启动,所有路由都将位于配置路由集合中,并且不会对性能产生进一步影响.

When the app starts all dynamic routes are there in the route collection and can be resolved as normal by angular. This adds some startup time to the app, depending on how many routes there are. But once the app has started, all routes are in the config routes collection and there is no further impact on performance.

请注意,仅当AOT为false时,此方法才有效.如果要将其与AOT一起使用,则必须将路由器注入app.component构造函数中,然后添加以下行: router.resetConfig(allRoutes); ,其中所有路由是引导前将路由推送到的阵列.

Note this works only if AOT is false. If you want to use this with AOT, you have to inject the router into the app.component constructor and then add this line: router.resetConfig(allRoutes);where all routes is the array you pushed the routes to before bootstrapping.

这篇关于Angular 2-从JSON数据动态路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆