Angular4:如何通过路由器

时间:2018-04-18 10:08:18

标签: angular typescript

继续这个问题Angular 4^ : How to have more than one child of a component with each child targeting its own router outlet,我能够将一些子组件注入多个父组件,现在我想将这些父组件中的数据async传递给子组件。尝试@Input,似乎无法获胜。

儿童

export class UserheaderComponent implements OnInit, AfterViewInit, OnChanges {
  loading;
  @Input() data;
  user = {
    name: '______________',
    icon: '',
    username: '_________',
    uid: '________'
  };
  constructor(private router: Router) {
  }

  goToUser(uid) {
    this.router.navigate(['user'], { queryParams: { uid: uid } });
  }

  ngOnInit() {
    this.user = this.data;
    console.log(this.data);
  }

  ngAfterViewInit() {
    console.log(this.data);
  }

  ngOnChanges(changes: SimpleChanges) {
    console.log(changes);
  }
}

家长Html

  <router-outlet name='userprofile-userhead' [data]="currentUser"></router-outlet>

家长TS

export class UserprofileComponent {
  public currentUser;

  constructor(
    private userFactory: UserFactory,
    private router: Router,
    private snack: MatSnackBar) {
    this.userFactory.checkSession(exists => {
      if (!exists) {
        return;
      }
      this.userFactory.getSessionUser((uid, user) => {
        this.currentUser = user;
      });
    });
  }
}

AND ROUTING

path: '', component: UserprofileComponent, outlet: 'userprofile', children: [
          { path: '', component: UserheaderComponent, outlet: 'userprofile-userhead' },
        ]

什么都没有传递给孩子,这种安排是否可能,或者我错过了什么?

无法使用共享服务。

每个组件都应该使用它自己的Id。想象一下,这是一个像上下文这样的帖子的时间表,就像一个社交媒体时间轴,这是帖子的头,你知道,用户图标,名称......用户名是。所以&#39;帖子&#39;组件会将其作为子项注入,并将其传递给用户object:{name:'...',username:'...'},因此我不知道服务将如何在此处执行。

现在,当我们在应用程序的某个地方,一个配置文件组件,搜索组件可能会调用此...

如果您仍然认为服务会这样做,请详细说明。

5 个答案:

答案 0 :(得分:4)

我找到了你,但我认为共享服务仍然是这个问题的答案

您可以尝试实施 pub / sub 服务,您可以在其中指定要订阅和广播的数据。

试试这个:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

/**
 * Publisher/Subscriber Service
 */
@Injectable()
export class PubSubService {

    private events: any = {};

    constructor() { }

    /**
     * Subscribes the instance of the assigned event name
     * @param eventName
     * Event name of the delegate
     */
    public On(eventName: PubSubEvents): Observable<any> {

        if (typeof this.events[eventName] === 'undefined') {
            this.events[eventName] = new Subject<any>();
        }

        return this.events[eventName].asObservable();
    }

    /**
     * Broadcast data to the specified event channel
     * @param eventName
     * Event name of the delegate
     * @param eventArgs
     * Arguments to pass through to the connected channel
     */
    public Broadcast(eventName: PubSubEvents, eventArgs: any) {
        if (!this.events[eventName]) {
            return;
        }

        this.events[eventName].next(eventArgs);
    }

}

//Your events
export declare type PubSubEvents =
    "OnChild1" | "OnChild2";

在父组件中,您根据需要订阅了所有活动。

<强>父

constructor(private pubsub: PubSubService){
  this.pubsub.On("OnChild1").subscribe((res) =>{ //Child 1 data}));
  this.pubsub.On("OnChild2").subscribe((res) =>{ //Child 2 data}));
}

在子组件中你必须这样做

儿童1

constructor(private pubsub: PubSubService){
  this.pubsub.Broadcast("OnChild1", "your_data")
}

儿童2

constructor(private pubsub: PubSubService){
  this.pubsub.Broadcast("OnChild2", "your_data")
}

答案 1 :(得分:1)

我认为在这种情况下,一个有效的选项是在UserheaderComponent的路由中添加一些参数,然后在组件启动时获取它并从服务获取预期数据。

首先,您需要将其添加到组件的路径路径

path: 'userHead/:userId' 

然后当你重定向到那个时你需要设置这个参数然后当组件初始化时你可以得到这个

this.activatedRoute.params.subscribe((params) => { const userHead= 
params['userId']; }

最后,基于该参数,您可以获得预期的数据形式服务。

如果您有一个孩子,请考虑直接使用组件

<userprofile-userhead name='userprofile-userhead' [data]="currentUser"> 
</userprofile-userhead>

而不是路由器插座。

答案 2 :(得分:1)

您可以将路由器路径设为 -

{ path: 'userHead/:Id' }

使用函数或直接导航组件:

  navigateUser(id) {
    this.router.navigate(['/userHead', id]);
  }

在您的子组件中,您可以通过订阅路由参数的ID来获取ID:

 ngOnInit() {
    this.ActivatedRoute.params.subscribe(params => {
      this.id = +params['id']; // (+) converts string 'id' to a number
      if (!isNaN(this.id)) {
       // logic here to check if id is something and put logic accordingly
    });
  }
  • 第二种方法是使用BehaviorSubjects。如果您需要了解它们,请告诉我,并尝试提供相同的代码。

答案 3 :(得分:1)

您可以将路径的自定义数据定义为:

[
   {path: 'inbox', data: {name: 'foo', age: 23}},
]

并且如下所示:

class ConversationCmp {
    constructor(r: ActivateRoute) {
         r.data.subscribe((p) => {
              console.log(p);
         });
    }
}

它在Route界面上定义:

export interface Route {
  path?: string;
  ...
  data?: Data;
}

在此信用:https://stackoverflow.com/a/45450982/4770754

答案 4 :(得分:0)

  

我假设您正在寻找以下流程:当某些时候   路径匹配,您希望路由器呈现父级(其中parent.ts是   拥有数据或通过http(s)和子提取数据。现在   在渲染孩子之后,你想要传递数据   父母对孩子......如果这是你的要求,这可能会有所帮助   你,

ParentComponent.ts

<router-outlet (activate)="onActivate($event)" name="child"></router-outlet>

ParentComponet.html

export class Child1Component implements OnInit {
data
  constructor() { }
  ngOnInit() {
  }
}

ChildComponent.ts

 <div *ngFor="let e of data">      {{e.username}}    </div>
   // this is for an example to display the data from parent in child

ChildComponent.html

export class ParentComponent  {
  parentdata: any = [{name: 'hello', username: 'world'}];
  myForm: FormGroup;
  event: any;
  constructor(private ds: DataService,private formBuilder: FormBuilder) {
    this.myForm = this.formBuilder.group({
      pdata: [[]]
    });
    this.myForm.get('pdata').valueChanges.subscribe(val => {
      if(this.event!=undefined)
        {
          this.event.data =  this.myForm.get('pdata').value;
        }
      })
   }
  ngAfterViewInit() {
       //this is for just for playing around with data of parent,
       // to check whether child receives the data or not
    setTimeout(function(myForm){

    let d = myForm.get('pdata').value;
    console.log(myForm.get('pdata').value);
    d.push({name: 'hello', username: 'world'});

  },3000,this.myForm)
  }
  onActivate(event){
    this.event = event;
    this.ds.getData().subscribe(x=>{
        this.myForm.get('pdata').setValue(x);
      })
  }

}

已编辑:无服务异步 - 使用formcontrol

  

在这里,我正在做的是每当父值改变时,   您要传递给孩子,我们需要更新子值   async ,因此在父级设置的位置使用 ValueChanges   child的值,现在即使你编辑父变量中的值,   它会反映到孩子身上。现在我相信这完成了   您的要求(没有共享服务之间的通信)   父母和孩子:))

在parent.ts中

{{1}}

希望这有帮助!!!