Brian F爱
Learn from a Google Developer Expert focused on Angular, Web Technologies, and Node.js from Portland, OR.
广告 ·ultimatecourses.com
Learn Angular the right way with Ultimate Courses

使用路由器的Angular2面包屑

A breadcrumb has been and still is a standard in user interface navigation on the web.We'll be implementing a breadcrumb into our Angular 2 application that uses Angular's路线r

演示

看看我的演示普利克:https://plnkr.co/edit/aneoyz?p=preview.

路线r

每个应用程序都可以有一个单一的路线r那个管理路线sin your application. You can read more aboutAngular 2's Routing and Navigation。To get started, let's take a quick look at my example routing configuration in theapp.routing.module.ts.file:

进口{module1pithproviders.}from'@ Angular / Core';进口{路线s路线rModule}from'@ Angular / Router';进口{IndexComponent}from'./index/index.component';进口{rootcomponent.}from'./root/root.component';进口{SigninComponent}from'./signin/signin.component';进口{SignupComponent}from'./signup/signup.component';const路线s路线s=[{路径''零件rootcomponent.儿童ren[{路径'signin'零件SigninComponentdata{breadcrumb'Sign In'}}{路径'signup'零件SignupComponentdata{breadcrumb'Sign Up'}}{路径''零件IndexComponent}]}];出口const路由module1pithproviders.=路线rModule托管路线s;

First, I import the necessary classes from the@ Angular / Core@angular/router包。然后,我导入将绑定到的必要组件path为每个指定路线

接下来,我定义了一个名为的常量路线s那是类型路线s,这只是一系列路线configuration objects. Each route has a path and the component for that path.

In my example application I have 3 children states for my root route:

  1. /- the IndexComponent will display the index.
  2. /登录 - SignInComponent将为我的应用程序显示一个标志。
  3. /注册 - SignupComponent将为您的应用程序显示注册表单。

这3条路线包裹在rootcomponent.。该/登入/注册路由两者都有自定义数据breadcrumb属性,它是面包屑链接标签的字符串。

我的应用程序@NgModuledeclares all of my components as well as my routing:

进口{NgModule}from'@ Angular / Core';进口{BrowserModule}from'@angular/platform-browser';进口{AppComponent}from'./app.component';进口{面包屑组合}from'./breadcrumb/breadcrumb.component';进口{rootcomponent.}from'./root/root.component';进口{IndexComponent}from'./index/index.component';进口{SigninComponent}from'./signin/signin.component';进口{SignupComponent}from'./signup/signup.component';进口{路由}from'./app.routing.module';@NgModule{进口s[BrowserModule路由]declarations[AppComponent面包屑组合IndexComponentrootcomponent.SigninComponentSignupComponent]bootstrap[AppComponent]}出口AppModule{}

Note that I have also defined a面包屑组合。We'll get to that in a minute.

另请注意,我已导入导出的路由从中的功能app.routing.module.ts.file.

AppComponent

好的,到目前为止,我们已经为我们的应用程序设置了一些基本路由。现在,让我们来看看AppComponent。该AppComponentwill contain both my<面包屑>as well as the

进口{零件OnInit}from'@ Angular / Core';@零件{选择器'my-app'template`

杀手应用 `}出口AppComponent实施OnInit{构造函数{}ngoninit.{}}

请注意有必要告诉路由器在哪里放置激活的路由内容。

面包屑组合

现在我们配置了我们的路由配置和我们的路由AppComponentcontaining the shell of our application we are ready to create our breadcrumb navigation. In this example I am usingBootstrap 3的CSS用于显示面包屑。You may need to customize the template as necessary for your application. Further, I am putting all of the template HTML inline in the@零件decorator data. You should most likely be specifying thetemplateUrl物业。

让我们来看看breadcrumb.component.tsfile:

进口{零件OnInit}from"@angular/core";进口{路线rActivatedRouteNavigationEndParamsPRIMARY_OUTLET}from"@angular/router";进口“RXJS / Add / Operator / Filter”;接口IBreadcrumb{标签;paramsParams;url;}@零件{选择器"breadcrumb"template``}出口面包屑组合实施OnInit{public面包屑IBreadcrumb[];/ * * * @class DetailComponent * @constructor */构造函数私人的activatedRouteActivatedRoute私人的路线r路线r{这个面包屑=[];}/ * * *走吧!* * @class DetailComponent * @method ngOnInit */ngoninit.{constROUTE_DATA_BREADCRUMB="breadcrumb";//订阅导航事件这个路线r活动filterevent=>event运算符NavigationEndsubscribeevent=>{//set breadcrumbsActivatedRoute=这个activatedRoute;这个面包屑=这个getBreadcrumbs;};}/** * Returns array of IBreadcrumb objects that represent the breadcrumb * * @class DetailComponent * @method getBreadcrumbs * @param {ActivateRoute} route * @param {string} url * @param {IBreadcrumb[]} breadcrumbs */私人的getBreadcrumbs路线ActivatedRouteurl=面包屑IBreadcrumb[]=[]IBreadcrumb[]{constROUTE_DATA_BREADCRUMB="breadcrumb";//获取子路线儿童renActivatedRoute[]=路线儿童ren;//如果没有更多的孩子,则返回if儿童ren长度===.0.{return面包屑;}//迭代每个孩子对于儿童of儿童ren{//verify primary routeif儿童出口!!==PRIMARY_OUTLET{继续;}//verify the custom data property "breadcrumb" is specified on the routeif!!儿童snapshotdatahasOwnPropertyROUTE_DATA_BREADCRUMB{return这个getBreadcrumbs儿童url面包屑;}//get the route's URL segmentRouteURL.=儿童snapshoturlmap分割=>分割路径join"/";//将路由URL附加到URLurl+=`/$ {RouteURL.}`;//add breadcrumbbreadcrumbIBreadcrumb={标签儿童snapshotdata[ROUTE_DATA_BREADCRUMB]params儿童snapshotparamsurlurl};面包屑pushbreadcrumb;//递归return这个getBreadcrumbs儿童url面包屑;}}}

这里有很多,所以让我们打破它。

Lines 1-3:

进口{零件OnInit}from'@ Angular / Core';进口{路线rActivatedRouteNavigationEndParamsPRIMARY_OUTLET}from'@ Angular / Router';进口'rxjs /添加/运算符/过滤器';
  • ActivatedRoutecontains data about the route for the current Component that is being displayed in the
  • NavigationEnd类represents the event when the navigation from one route to another has completed. We'll use this to filter the stream of events coming from the router so that we can listen for when the navigation has completed.
  • primary_oulet是表示路由名称的常量字符串。这默认为字符串“primary”。在我的示例应用程序中,我不使用多个命名路由。我只有一个出口,或者元素,在我的模板中。如果您在应用程序中使用多个命名路由,我们将检查路由是否是主要的路由,并将为填充器使用此操作。
  • Finally, I import thefilter()操作员从反应图书馆

Lines 5-9:

接口IBreadcrumb{标签;paramsParams;url;}
  • 我定义了一个名为的新界面IBreadcrumb
  • A breadcrumb has two required properties:标签andurl,两者都是字符串。该params属性不是必需的,是类型Params。This is used to pass along params in our breadcrumb links.

Lines 11-21:

@零件{选择器"breadcrumb"template``}
  • My component will use the selector "breadcrumb". If you recall I had a<面包屑>element defined in the template of theAppComponent
  • 我的模板HTML是内联定义的。因为这是一个很短的例子,这在这种情况下有效。但是,你最有可能使用templateUrl属性要定义外部.html文件。
  • 我喜欢在面包屑中包含一个静态的“家”链接。这只是使用routerlink指令返回到我的应用程序的根目录。
  • 然后我使用Ngfor.指令迭代的指令breadcrumb对象。这些对象将是类型IBreadcrumb- 先前声明的接口。
  • 在我们的里面Ngfor.loop I output the link to the route for each breadcrumb using the values stored in theIBreadcrumbobject. We'll populate these objects in our controller'sngoninit.()method.

Lines 24-31:

public面包屑IBreadcrumb[];构造函数私人的activatedRouteActivatedRoute私人的路线r路线r{这个面包屑=[];}
  • 首先,我定义了名为的公共变量面包屑这是一系列IBreadcrumb对象。
  • My构造函数()函数使用依赖注入(di)获取实例ActivatedRoute路线r
  • 在我的构造函数中,我设置了面包屑值为空数组。

Lines 33-43:

ngoninit.{//订阅导航事件这个路线r活动filterevent=>event运算符NavigationEndsubscribeevent=>{//set breadcrumbsActivatedRoute=这个activatedRoute;这个面包屑=这个getBreadcrumbs;};}
  • In thengoninit.method we are going subscribe to an可观察到的对于导航在路由器结束时。
  • 路线r班级有一个名为的物业活动。该文档表示此“返回路线事件的可观察到”。这些事件包括:启动导航,取消导航和导航结束(以及可能其他人)。
  • 我们将使用RXJ的过滤器运算符过滤掉任何不是实例的事​​件NavigationEnd类。We are only concerned about updating the application's breadcrumb when the navigation has completed.
  • 然后我们subscribe()to the stream and use the fat-arrow syntax for defining a function that will be invoked whenever theNavigationEndevent occurs.
  • 在匿名函数内(其这个scope is bound to the BreadcrumbComponent instance) we get the root route for the currently activated route. The root route is the top of the route tree, or the first route if you like to think about it that way.
  • In thegetBreadcrumbs()method we will use this路线to recursively determine the primary routes for the currently activate route.

Lines 45-87:

私人的getBreadcrumbs路线ActivatedRouteurl=面包屑IBreadcrumb[]=[]IBreadcrumb[]{constROUTE_DATA_BREADCRUMB="breadcrumb";//获取子路线儿童renActivatedRoute[]=路线儿童ren;//如果没有更多的孩子,则返回if儿童ren长度===.0.{return面包屑;}//迭代每个孩子对于儿童of儿童ren{//verify primary routeif儿童出口!!==PRIMARY_OUTLET{继续;}//verify the custom data property "breadcrumb" is specified on the routeif!!儿童snapshotdatahasOwnPropertyROUTE_DATA_BREADCRUMB{return这个getBreadcrumbs儿童url面包屑;}//get the route's URL segmentRouteURL.=儿童snapshoturlmap分割=>分割路径join"/";//将路由URL附加到URLurl+=`/$ {RouteURL.}`;//add breadcrumbbreadcrumbIBreadcrumb={标签儿童snapshotdata[ROUTE_DATA_BREADCRUMB]params儿童snapshotparamsurlurl};面包屑pushbreadcrumb;//递归return这个getBreadcrumbs儿童url面包屑;}return宽面包;}
  • 以下是实现的大部分 - 我们将递归地通过路由树来确定主路径,以便在每个步骤中获取必要的面包屑信息,以返回Ibreadcrumb对象的数组。
  • 请注意urland面包屑arguments are optional, and have default values defined.
  • First I define a constant string namedROUTE_DATA_BREADCRUMB。该value for this is simply "breadcrumb". Back when I defined our routes in theapp.routing.module.ts.文件我包含大多数路由的自定义数据。自定义数据是具有命名的属性的对象breadcrumb。We can access that custom data to set the标签每个价值IBreadcrumb我们将创建和推动我们的对象面包屑数组中。
  • 接下来,我得到了数组儿童ren对于传入方法的路线。最初,这是我们的根路线。
  • 如果路线没有孩子,那么我们已经到达了路由树的末尾。因此,我们只需返回我们创建的面包屑数组。
  • 现在我们准备好迭代每个孩子。
  • For each child route, we are only interested in the primary route.
  • And, we also want to ensure that the route's custom data includes the "breadcrumb" property. If not, continue to build the breadcrumb using it's child routes.
  • Now that we know that we have the primary route, we need to build the URL for the route. There are two ways to do this: using observables or using the snapshot of the activated route at this time. I chose to use the snapshot approach as it's a bit simpler. And, I don't believe using the observable is necessary. The snapshot property is an instance of Angular'sactivatedRoutesnapshot.类。在该类中,我们拥有名为URL的属性,该属性是一个URLsegment对象数组。我用map()获取每个细分的功能路径property value, and then join these using the forward-slash as the separator "/".
  • 然后,我使用前向斜杠向我的路由的URL前缀,以便routerlink值是绝对的URL。
  • Finally, I create a new object that is of typeIBreadcrumb并为每个属性分配值:

    • 标签
    • params那and
    • url
  • 然后我将此新对象推到我的数组上面包屑
  • 一旦我们完成了这个主要路线,那么我们就不再关心兄弟姐妹儿童。所以,我们可以突破循环。
  • Finally, we recurively invoke thegetBreadcrumbs()方法,通过主要儿童路线那along with theurland array of宽面包that we have built so far.

pl

以下是普利克的代码的示例:

Brian F爱

Hi, I'm Brian. I am interested in TypeScript, Angular and Node.js. I'm married to my best friend Bonnie, I live in Portland and I ski (a lot).