当父组件上的变量发生更改时,重新加载子组件。 Angular2

时间:2016-10-26 08:06:37

标签: angular

我有一个MasterComponent,可以加载页眉,页脚,侧边栏等。在标题上有一个下拉列表,其选项在用户登录后设置。我希望标题保持不变,即使我导航到不同的加载路径不同的儿童成分。表示所选子选项不应更改,并且所有子组件都应该可以访问下拉值。在更改下拉值时,应更新/重新加载当前子组件。

我该如何处理这个问题?我想要事件监听器的功能。从MasterComponent更改模型后,重新加载当前子组件。在MasterComponent的变量变量更新中,ChildComponent将监听更新并运行某个函数或再次调用某个API并重新加载ChildComponent。

// routes
const appRoutes: Routes = [
    {
        path: '',
        redirectTo: 'login',
        pathMatch: 'full',
    },
    {   path: 'login', component: LoginComponent },
    {   path: 'logout', component: LogoutComponent },
    {
        path: '',
        component: MasterComponent,
        canActivate: [AuthGuard],
        children: [
            { path: 'record/create', component: RecordCreateComponent }, // create record for selectedRestaurant in MasterComponent
            { path: 'record/', component: RecordComponent }, // shows all record of current selectedRestaurant in MasterComponent
            { path: 'record/:id/update', component:RecordUpdateComponent }, // show form to edit record having id
            { path: 'record/:id', component: RecordComponent }, // show record details having id
        ]
    },
    { path: '**', redirectTo: 'login' }
];
// MasterComponent
@Component({
    selector: 'master',
    templateUrl: templateUrl,
    styleUrls:[styleUrl1]

})
export class MasterComponent implements AfterViewInit, OnInit{
    restaurants: Array<Restaurant> = [];
    user:User;
    selectedRestaurant: Restaurant;

    constructor(private router: Router, private storageHelper:StorageHelper){
    }
    ngAfterViewInit() {
    }
    ngOnInit(){
        this.user = JSON.parse(this.storageHelper.getItem('user'));
        this.restaurants = this.user.restaurants;
        this.selectedRestaurant = this.restaurants[0];
        this.router.navigate(['/record/' + this.selectedRestaurant.id]);
    }
    onRestaurantChange(){
        this.router.navigate(['/record/' + this.selectedRestaurant.id]);
    }
    createRecord(){
    }
}

enter image description here

5 个答案:

答案 0 :(得分:26)

使用@Input将您的数据传递给子组件,然后使用ngOnChangeshttps://angular.io/api/core/OnChanges)查看@Input是否即时更改。

答案 1 :(得分:5)

在Angular上更新包含其模板的组件,有一个直接的解决方案,在您的ChildComponent上具有@Input属性并添加到@Component装饰器changeDetection: ChangeDetectionStrategy.OnPush,如下所示:

import { ChangeDetectionStrategy } from '@angular/core';

@Component({
    selector: 'master',
    templateUrl: templateUrl,
    styleUrls:[styleUrl1],
    changeDetection: ChangeDetectionStrategy.OnPush    
})

export class ChildComponent{
  @Input() data: MyData;
}

这将完成检查输入数据是否已更改并重新渲染组件的所有工作

答案 2 :(得分:1)

更新@Vladimir Tolstikov的答案

创建一个使用ngOnChanges的子组件。

ChildComponent.ts ::

import { Component, OnChanges, Input } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'child',
  templateUrl: 'child.component.html',
})

export class ChildComponent implements OnChanges {
  @Input() child_id;

  constructor(private route: ActivatedRoute) { }

  ngOnChanges() {
    // create header using child_id
    console.log(this.child_id);
  }
}

现在在 MasterComponent 的模板中使用它,并将数据传递给 ChildComponent ,例如:

<child [child_id]="child_id"></child>

答案 3 :(得分:1)

以防万一,我们无法控制子组件,例如第三方库组件。

我们可以使用*ngIfsetTimeout从父级重置子级组件,而无需更改子级组件。

.template:

.ts:

show:boolean = true

resetChildForm(){
   this.show = false;

   setTimeout(() => {
      this.show = true
    }, 100);
}

答案 4 :(得分:0)

您可以将@input与ngOnChanges结合使用,以查看发生的更改。

参考: https://angular.io/api/core/OnChanges

(或)

如果要在多个组件或路由之间传递数据,请使用Rxjs方式。

Service.ts

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

@Injectable({ providedIn: 'root' })
export class MessageService {
private subject = new Subject<any>();

sendMessage(message: string) {
    this.subject.next({ text: message });
}

clearMessages() {
    this.subject.next();
}

getMessage(): Observable<any> {
    return this.subject.asObservable();
}
}

Component.ts

import { Component, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';

import { MessageService } from './_services/index';

@Component({
selector: 'app',
templateUrl: 'app.component.html'
})

export class AppComponent implements OnDestroy {
messages: any[] = [];
subscription: Subscription;

constructor(private messageService: MessageService) {
    // subscribe to home component messages
    this.subscription = this.messageService.getMessage().subscribe(message => {
      if (message) {
        this.messages.push(message);
      } else {
        // clear messages when empty message received
        this.messages = [];
      }
    });
}

ngOnDestroy() {
    // unsubscribe to ensure no memory leaks
    this.subscription.unsubscribe();
}
}

参考: http://jasonwatmore.com/post/2019/02/07/angular-7-communicating-between-components-with-observable-subject