Angular2 using @Inputs with <router-outlet>s
I have a sub-navigation in my page that displays some subviews below a common main view. I would like to pass an object to the subviews through the <router-outlet>
so that I can retrieve the data once in the main component and just share it with my sub components.
Note: If I include the directive <one></one>
in the main.html it works but this isn't my desired behavior.
Main View:
<h1>Details</h1>
<a [router-link]="['./sub1']">One</a> |
<a [router-link]="['./sub2']">Two</a> |
<a [router-link]="['./sub3']">Three</a>
<hr/>
<router-outlet [data]="maindata"></router-outlet>
Sub View 1:
<h2>{{ data.name }}</h2>
...
Main View:
@Component({
selector: 'main-detail',
directives: [ROUTER_DIRECTIVES],
templateUrl: './main.html'
})
@RouteConfig([
{ path: '/', redirectTo: '/one' },
{ path: '/one', as: 'One', component: OneComponent },
{ path: '/two', as: 'Two', component: TwoComponent },
{ path: '/three', as: 'Three', component: ThreeComponent }
])
export class MainComponent {
maindata: Object = {name:'jim'};
}
Sub View 1:
@Component({
selector: 'one',
directives: [CORE_DIRECTIVES],
inputs: ['data'],
templateUrl: './one.html'
})
export class OneComponent {
@Input() data;
}
If it's simple data you can pass them through RouteParams
<a [router-link]="['./sub3'],{name:'jim'}">Three</a>
then in your sub view
@Component({
selector: 'one',
directives: [CORE_DIRECTIVES],
templateUrl: './one.html'
})
export class OneComponent {
data: any;
constructor(params: RouteParams){
this.data = params.get('data');
}
}
You can also setup the route to always pass params from the component by moving the RouterConfig INSIDE the component (Note, this is not how it's normally done):
export class AppCmp {
history: string[] = [];
constructor(public list: PersonalizationList,
private router_: Router) {
list.get('histoy', (response) => {
this.history = response;
});
router_.config([
{ path: '/', component: HomeCmp, as: 'Home', data: this.history },
{ path: '/about', component: AboutCmp, as: 'About' }
]);
}
}
Credit to the Source
If you are going to do something more complex I suggest using a service to communicate between routes/components. It's actually the way I prefer to do it.
Sample Service:
import {Injectable} from 'angular2/angular2';
@Injectable()
export class CarsService {
list1: array<any> = ['a','b','c','d'];
list2: array<any>;
constructor() {
this.list2 = [1,2,3,9,11];
}
}
How you Inject a service:
export class Cars {
constructor(cars:CarsService) {
this.cmpList1 = cars.list1;
this.cmpList2 = cars.list2;
}
}
This way you can use the service to communicate regardless of parent/child or other weird restrictions.
Looks like syntax has been changed. Below works for me ~Angular4.0.0
HTML (Pass Route Parameters)
<li><a [routerLink]="['/templatecreate',{mode:'New'}]">New Job</a></li>
Component
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.getTemplate();
this.sub = this.route.params.subscribe(params => { this.id = params['mode'];
console.log("Routing Mode", this.id);
});
}
I think the proper Angular2 way to be passing data is via Dependency Injections (by using a Service) otherwise the user will be able to see the data you're passing in the browser's URL.
Also, using a Service will allow for "Separation of Concerns", meaning that Component A shouldn't be dependent on Component B.
Dependency Injection Links:
1) https://angular.io/guide/dependency-injection
2) https://angular.io/guide/dependency-injection-in-action
3) https://www.youtube.com/watch?v=MJrw43GP2u0