dra*_*mnl 216 typescript angular
在我的一个Angular 2路线的模板(FirstComponent)中,我有一个按钮
first.component.html
<div class="button" click="routeWithData()">Pass data and route</div>
Run Code Online (Sandbox Code Playgroud)
我的目标是实现:
按钮单击 - >路由到另一个组件,同时保留数据,而不使用其他组件作为指令.
这就是我试过的......
第一种方法
在同一视图中,我存储基于用户交互收集相同的数据.
first.component.ts
export class FirstComponent {
constructor(private _router: Router) { }
property1: number;
property2: string;
property3: TypeXY; // this a class, not a primitive type
// here some class methods set the properties above
// DOM events
routeWithData(){
// here route
}
}
Run Code Online (Sandbox Code Playgroud)
一般情况下我路由SecondComponent通过
this._router.navigate(['SecondComponent']);
Run Code Online (Sandbox Code Playgroud)
最终传递数据
this._router.navigate(['SecondComponent', {p1: this.property1, p2: property2 }]);
Run Code Online (Sandbox Code Playgroud)
而带参数的链接的定义是
@RouteConfig([
// ...
{ path: '/SecondComponent/:p1:p2', name: 'SecondComponent', component: SecondComponent}
)]
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是我猜我无法传递复杂数据(例如像property3这样的对象)in-url;
第二种方法
另一种方法是在FirstComponent中包含SecondComponent作为指令.
<SecondComponent [p3]="property3"></SecondComponent>
Run Code Online (Sandbox Code Playgroud)
但是我想要路由到该组件,而不是包含它!
第三种方法
我在这里看到的最可行的解决方案是使用服务(例如FirstComponentService)
虽然这种方法似乎完全可行,但我想知道这是否是实现目标的最简单/最优雅的方式.
一般来说,我想知道我是否缺少其他可能的方法来在组件之间传递数据,特别是在代码量较少的情况下
Gün*_*uer 159
更新4.0.0
有关详细信息,请参阅Angular文档https://angular.io/guide/router#fetch-data-before-navigating
原版的
使用服务是可行的方法.在路径参数中,您应该只传递要在浏览器URL栏中反映的数据.
另见https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
RC.4附带的路由器重新介绍 data
constructor(private route: ActivatedRoute) {}
Run Code Online (Sandbox Code Playgroud)
const routes: RouterConfig = [
{path: '', redirectTo: '/heroes', pathMatch : 'full'},
{path : 'heroes', component : HeroDetailComponent, data : {some_data : 'some value'}}
];
Run Code Online (Sandbox Code Playgroud)
class HeroDetailComponent {
ngOnInit() {
this.sub = this.route
.data
.subscribe(v => console.log(v));
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
Run Code Online (Sandbox Code Playgroud)
另见Plunker,网址:https://github.com/angular/angular/issues/9757#issuecomment-229847781
Utp*_*Das 60
我想因为我们在角度2中没有$ rootScope类似于角度1.x. 我们可以使用angular 2共享服务/类,而在ngOnDestroy中将数据传递给服务,并在路由后从ngOnInit函数中的服务获取数据:
这里我使用DataService来共享英雄对象:
import { Hero } from './hero';
export class DataService {
public hero: Hero;
}
Run Code Online (Sandbox Code Playgroud)
从第一页组件传递对象:
ngOnDestroy() {
this.dataService.hero = this.hero;
}
Run Code Online (Sandbox Code Playgroud)
从第二页组件获取对象:
ngOnInit() {
this.hero = this.dataService.hero;
}
Run Code Online (Sandbox Code Playgroud)
这是一个例子:plunker
Was*_*aga 46
Angular 7.2.0 引入了在路由组件之间导航时传递数据的新方法:
@Component({
template: `<a (click)="navigateWithState()">Go</a>`,
})
export class AppComponent {
constructor(public router: Router) {}
navigateWithState() {
this.router.navigateByUrl('/123', { state: { hello: 'world' } });
}
}
Run Code Online (Sandbox Code Playgroud)
或者:
@Component({
selector: 'my-app',
template: `
<a routerLink="/details" [state]="{ hello: 'world' }">Go</a>`,
})
export class AppComponent {}
Run Code Online (Sandbox Code Playgroud)
要读取状态,您可以window.history.state在导航完成后访问属性:
export class PageComponent implements OnInit {
state$: Observable<object>;
constructor(public activatedRoute: ActivatedRoute) {}
ngOnInit() {
this.state$ = this.activatedRoute.paramMap
.pipe(map(() => window.history.state))
}
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*ila 21
<div class="button" click="routeWithData()">Pass data and route</div>
Run Code Online (Sandbox Code Playgroud)
以角度6或其他版本执行此操作的最简单方法我希望只需使用您要传递的数据量来定义路径
{path: 'detailView/:id', component: DetailedViewComponent}
Run Code Online (Sandbox Code Playgroud)
正如你从我的路线定义中看到的那样,我已经/:id通过路由器导航添加了要传递给组件的数据.因此,您的代码看起来像
<a class="btn btn-white-view" [routerLink]="[ '/detailView',list.id]">view</a>
Run Code Online (Sandbox Code Playgroud)
为了读取id组件上,只需要导入ActivatedRoute 像
import { ActivatedRoute } from '@angular/router'
Run Code Online (Sandbox Code Playgroud)
并在ngOnInit是您检索数据
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
this.id = params['id'];
});
console.log(this.id);
}
Run Code Online (Sandbox Code Playgroud)
你可以在这篇文章中阅读更多内容 https://www.tektutorialshub.com/angular-passing-parameters-to-route/
PeS*_*PeS 21
现在是 2019 年,这里的许多答案都会起作用,具体取决于您想要做什么。如果你想传递一些在 URL 中不可见的内部状态(参数,查询),你可以state从 7.2 开始使用(正如我今天学到的:) )。
从博客(Tomasz Kula 致谢)-您导航到路线....
...来自 ts: this.router.navigateByUrl('/details', { state: { hello: 'world' } });
...来自 HTML 模板: <a routerLink="/details" [state]="{ hello: 'world' }">Go</a>
并在目标组件中拾取它:
constructor(public activatedRoute: ActivatedRoute) {}
ngOnInit() {
this.state$ = this.activatedRoute.paramMap
.pipe(map(() => window.history.state))
}
Run Code Online (Sandbox Code Playgroud)
晚了,但希望这对最近使用 Angular 的人有所帮助。
Sha*_*wal 12
我从这个页面查看了每个解决方案(并尝试了一些),但我不相信我们必须实现一种黑客式的方式来实现路由之间的数据传输。
simple 的另一个问题history.state是,如果您在state对象中传递特定类的实例,则在接收它时它将不是该实例。但它将是一个简单的 JavaScript 对象。
所以在我的Angular v10 (Ionic v5) 应用程序中,我做了这个——
this.router.navigateByUrl('/authenticate/username', {
state: {user: new User(), foo: 'bar'}
});
Run Code Online (Sandbox Code Playgroud)
在导航组件 ( '/authenticate/username') 中,在ngOnInit()方法中,我使用this.router.getCurrentNavigation().extras.state-
ngOnInit() {
console.log('>>authenticate-username:41:',
this.router.getCurrentNavigation().extras.state);
}
Run Code Online (Sandbox Code Playgroud)
我得到了传递的所需数据-
O95*_*O95 11
路线:
{ path: 'foo-route', component: FooComponent, data: { myData: false } },
Run Code Online (Sandbox Code Playgroud)
在组件中访问数据对象一次:
pipe(take(1))立即取消订阅,因此不会出现内存泄漏,无需手动取消订阅
constructor(private activatedRoute: ActivatedRoute) { ... }
ngOnInit(): void {
this.activatedRoute.data.pipe(take(1)).subscribe((data) => {
console.log(data); // do something with the data
});
}
Run Code Online (Sandbox Code Playgroud)
编辑:新的firstValueFrom()可能会更好
使用 ActiveRoute 的解决方案(如果你想通过路由传递对象 - 使用 JSON.stringfy/JSON.parse):
发送前准备对象:
export class AdminUserListComponent {
users : User[];
constructor( private router : Router) { }
modifyUser(i) {
let navigationExtras: NavigationExtras = {
queryParams: {
"user": JSON.stringify(this.users[i])
}
};
this.router.navigate(["admin/user/edit"], navigationExtras);
}
}
Run Code Online (Sandbox Code Playgroud)
在目标组件中接收您的对象:
export class AdminUserEditComponent {
userWithRole: UserWithRole;
constructor( private route: ActivatedRoute) {}
ngOnInit(): void {
super.ngOnInit();
this.route.queryParams.subscribe(params => {
this.userWithRole.user = JSON.parse(params["user"]);
});
}
}
Run Code Online (Sandbox Code Playgroud)
不是我的一些超级聪明人(tmburnell)建议重写路线数据:
let route = this.router.config.find(r => r.path === '/path');
route.data = { entity: 'entity' };
this.router.navigateByUrl('/path');
Run Code Online (Sandbox Code Playgroud)
可以看出这里的评论。
我希望有人会觉得有用
小智 7
我这另一种方法对这个问题不好。我觉得最好的方法是按角度查询参数,Router它有两种方式:
直接传递查询参数
有了这个代码,你可以浏览到url通过params在HTML代码中:
<a [routerLink]="['customer-service']" [queryParams]="{ serviceId: 99 }"></a>
Run Code Online (Sandbox Code Playgroud)
通过传递查询参数
Router
您必须在自己的路由器中注入路由器constructor:
constructor(private router:Router){
}
Run Code Online (Sandbox Code Playgroud)
现在像这样使用:
goToPage(pageNum) {
this.router.navigate(['/product-list'], { queryParams: { serviceId: serviceId} });
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您想阅读Router其他内容Component,则必须使用ActivatedRoutelike:
constructor(private activateRouter:ActivatedRouter){
}
Run Code Online (Sandbox Code Playgroud)
并且subscribe:
ngOnInit() {
this.sub = this.route
.queryParams
.subscribe(params => {
// Defaults to 0 if no query param provided.
this.page = +params['serviceId'] || 0;
});
}
Run Code Online (Sandbox Code Playgroud)
小智 5
第三种方法是在组件之间共享数据的最常用方法.您可以注入要在相关组件中使用的项目服务.
import { Injectable } from '@angular/core';
import { Predicate } from '../interfaces'
import * as _ from 'lodash';
@Injectable()
export class ItemsService {
constructor() { }
removeItemFromArray<T>(array: Array<T>, item: any) {
_.remove(array, function (current) {
//console.log(current);
return JSON.stringify(current) === JSON.stringify(item);
});
}
removeItems<T>(array: Array<T>, predicate: Predicate<T>) {
_.remove(array, predicate);
}
setItem<T>(array: Array<T>, predicate: Predicate<T>, item: T) {
var _oldItem = _.find(array, predicate);
if(_oldItem){
var index = _.indexOf(array, _oldItem);
array.splice(index, 1, item);
} else {
array.push(item);
}
}
addItemToStart<T>(array: Array<T>, item: any) {
array.splice(0, 0, item);
}
getPropertyValues<T, R>(array: Array<T>, property : string) : R
{
var result = _.map(array, property);
return <R><any>result;
}
getSerialized<T>(arg: any): T {
return <T>JSON.parse(JSON.stringify(arg));
}
}
export interface Predicate<T> {
(item: T): boolean
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
304890 次 |
| 最近记录: |