简体   繁体   中英

Creating Link Component in Angular2

Looking to create a wrapper component in Angular 2, similar to the way that react-bootstrap and other tools allow you to create wrapper components. Looking to be able to re-use the component so we don't have to repeat the structure every time.

Essentially, I want to be able to re-use a component that has this rough structure:

'use strict';
import { ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
import {Component, Input} from 'angular2/core';

@Component({
  selector: 'nav-item',
  directives: [ROUTER_DIRECTIVES],
  providers: [ROUTER_PROVIDERS],
  template: `
  <li>
     <a routerLink="<SPECIFIED ROUTE>">
      <ng-content></ng-content>
    </a>
  </li>
  `,
})

export default class NavLink {
  public static $injector: Array<string> = [];
  @Input() to: string;
  constructor() {}
}

And then

'use strict';

import {Component} from 'angular2/core';
import NavLink from './link.component';

@Component({
  selector: 'Navbar',
  host: {'class': 'navbar'},
  directives: [NavLink],
  template: `
    <div class="row">
      <ul>
        <nav-item to="/Foo">
        </nav-item>
      </ul>
    </div>
  `,
})

export default class Nav {
  constructor() {}
}

I know routerLink expects an array specification, but I'm wondering what the angular2 way of passing data from a parent component to a child component is and then accessing that data within the child component. I know the @Input decorator lets you specify a property to pass in and then you can bind to that using [] in the parent component, but I'm not sure as to the best access method within a component :)

I've tried:

<a routerLink="{{ to }}">

But angular2 complains about not being able to .forEach over the expected array specification (which makes sense).

EXCEPTION: TypeError: linkParams.forEach is not a function in [{{ to }} in NavLink@2:8]

I'm just not sure of the way that passing data into a bound property works; I come from more of a React background, so things are passed via props and you can inspect the type and it's pretty much just normal JavaScript object-passing.

What's the best way access that bound property and/or is this an antipattern I'm trying to implement?

I think of Angular2 Components as more powerful versions of React components, you can do more with less. I am not sure if this is better or worse, but just know you probably won't need to abstract as many things, or want to abstract as many things as you did in React. This is because of more prebuilt tools, which again might give you less freedom to do certain things and make it much faster to do other things.

I will also say, passing values back and forth in React at least for me was more intuitive.

So to get on with it here is a little bit about the right syntax and how Routing works in Angular2. Although you probably already know this, I am just going to post it anyways in case someone else reads this.

You would start with a @RouteConfig decorator that takes an array of objects and makes them available to your app. So in your case you would have something like:

@RouteConfig([
    {path: '/wine', name: 'Wine', component: Wine},
    //or just so you can see it in case you haven't how to add params!
    {path: '/wine/:type', name: 'WineType', component: WineType}
])

Now to access the routerlink you would pass it:

<a [routerLink] = "['/Wine'] </a>
<a [routerLink] = "['/WineType', {type: type.ID}]}> </a>

Now to answer your question for passing things back and forth.

For your first component you should put this:

  <li>
     <a routerLink="[to]">
      <ng-content></ng-content>
    </a>
  </li>

So you'll most likely want to surround your to string in square brackets so the syntax is correct for routerLink's.

And for your second component Navbar the syntax is fairly close but not exact.

   <div class="row">
      <ul>
        <nav-item [to]="/Wines"></nav-item>
      </ul>
    </div>

This says pass "/Wines" into the variable [to] in the child component. It must be in square brackets.

And to add on if you had a list of navbar items you could do something like this:

'use strict';

import {Component} from 'angular2/core';
import NavLink from './link.component';

@Component({
  selector: 'Navbar',
  host: {'class': 'navbar'},
  directives: [NavLink],
  template: `
    <div class="row">
      <ul>
        <nav-item *ngFor="#item of items [to]=item>
        </nav-item>
      </ul>
    </div>
  `,
})

export default class Nav {
  all_my_routes: Array<string> = [];
  constructor() {
    all_my_routes = ['/Wine', '/OtherWine', '/Beer']
  }
}

Which should iterate through your Nav items.

Also a side not because I think it's a bit of a silly keyword and it still gets me about 50% of the time, is make sure you use of between your ngFor #item of items .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM