如何在Angular中从子路由组件访问父组件属性?

9

我是Angular的新手,目前遇到了问题。

我知道通过将[parentData]="var"注入到子选择器<>中,可以简单地在父组件和子组件之间共享数据。

但是当使用路由时,我只有一个router-outlet,并且无法将[parentData]绑定到它上面,因为这会抛出错误。

最好和最简单的方法是从子路由中访问父组件的属性?

项目位于stackblitz这里

我需要在子组件中显示来自父组件的产品。

版本:(Angular 5)


你不能直接从一个带有 router-outlet 的组件传递变量到另一个组件。你必须使用服务来共享数据,在应用程序的生命周期中,服务是相同的。在 https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service 中,你可以看到如何通过服务进行父子组件之间的通信,但如果你只想要更简单的方法,请参考 https://stackoverflow.com/questions/44914707/angular-2-shared-service-to-pass-data-to-component-to-component - Eliseo
解析器是一个服务,它专门为此目的而完成:https://angular.io/guide/router#resolve-guard - Ayyash
2个回答

12

是的,这很简单,当您想要传递给位于router-outlet中的组件时,您需要使用services。实际上,在您进入正确的路径之前,该组件在模板中不存在,因此常规绑定在这里不起作用。

因此,解决此问题的最佳方法是创建一些简单的服务

在服务中

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

@Injectable()
export class DataTransferService {

  private products= new BehaviorSubject<any>([]);
  cast= this.products.asObservable();

  sendAnything(data) {
    this.products.next(data);
  }

}

然后将您的服务注入到父组件和子组件的构造函数中

在父组件中

 constructor(private dataTransfer: DataTransferService){}

然后创建一个方法

 shareData(data){
    this.dataTransfer.sendAnything(data) // to send something
}

并从 parent.component.html 中调用它

(click)="shareData(data)" // data is the parent data that you want to share

在子组件中

在 ngOnInit 方法里面添加:

 ngOnInit() {
   this.dataTransfer.products.subscribe(res=> this.var = res) // var is the property that you want to assign the data to it.
 }

获取数据并对其进行操作。
更多信息和示例可在文档中找到。


非常感谢您的回答,我现在会尝试一下。但是我以前没有使用过Subjects,您的Variable、sourceProductName和sourceYourVariable代表什么? - shireef khatab
抱歉,我打错了一些字。Subject是一种类型的可观察对象,我们可以控制并调用.next()方法向流发送新值,yourVariable是一个实际的Observable,您可以订阅并监听从应用程序中其他地方发送的任何内容。 - Kraken
我已经编辑了答案,以帮助像我一样刚开始学习Angular的人。我花费了时间搜索和弄清如何利用答案,因此对我来说,负投票并不公平。谢谢。 - shireef khatab
如果它是正确的答案,您需要将其标记为正确答案。没问题,希望能对某些人有所帮助。 - Kraken
如果您投了反对票,您是否可以将其删除? - shireef khatab
这对我没有起作用,文档使用的是 Subject 而不是 BehaviorSubject,使用 Subject 可以解决问题。https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service - Exlord

5
一方面,在router-outlet标签中不能传递输入,因为由路由添加的组件将成为该标签的兄弟而不是替换它。
另一方面,当您的Angular应用程序变得越来越复杂时,从父组件传递相同输入到子组件将不再是正确的做法。
在您的情况下,处理产品变量的最佳方法是在产品服务中声明它为BehaviorSubject。
   prodcuts:Subject<IProducts[]> = new BehaviorSubject<IProducts[]>([]);

在父组件中,您发送收到的数据:

ngOnInit() { 
    this._productsService.getProducts()
        .subscribe(
          data => {this.products = data;
          this._productsService.prodcuts.next(data);
          },
          error => this.errMsg = error
        );    
}

最后,在子客户端中,您需要订阅在服务中声明的行为主题:

export class ChildComponent implements OnInit {
public products = [];

constructor(private _productsService: ProductsService ) { 
}

ngOnInit() {
    this._productsService.prodcuts
    .subscribe(
      data => {
       {this.products = data;
      }
    );    
  } 
}

这似乎是一个高效的解决方案,我很快就会尝试。谢谢。 - shireef khatab
谢谢您应用我的之前与productService相关的代码,我后来更新了它以简化操作,但是您的代码将对我很有帮助。我会在几个小时内处理它,非常感谢你。 - shireef khatab
请问能否解释一下:在子组件中,订阅产品和订阅 getProducts() 有什么区别,就像我们在父组件内部所做的那样?我不太清楚。 - shireef khatab

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接