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

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

问题描述

在 Angular 2.0 stable 中,我有一个应用程序,我必须在其中根据收到的 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?

推荐答案

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

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 const 也很重要,以便您可以将新的动态路由推送到您的 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 组件函数的原因:

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

当应用程序启动时,所有动态路由都在路由集合中,并且可以通过 angular 正常解析.这会为应用程序增加一些启动时间,具体取决于有多少路由.但是一旦应用启动,所有路由都在配置路由集合中,对性能没有进一步的影响.

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天全站免登陆