【问题标题】:How can I send list from one nested component to another nested component ? Angular如何将列表从一个嵌套组件发送到另一个嵌套组件?角
【发布时间】:2018-12-05 02:56:53
【问题描述】:

我正在处理屏幕左侧有类别的项目,通过按屏幕中间的每个类别应该显示属于所选类别的文章/产品。

我很简单地把左边的分类画成这样:

category: Category[];

ngOnInit() {
    this.category= this._activatedRoute.snapshot.data['category'];
}

在我的模板 .html 文件中,我只是显示了它们并在每个文件上附加了事件:

<div class="tab-content categories-tab-content">
  <div class="tab-pane" id="food">
    <ul>
        <li *ngFor="let c of category;">
          <button type="button" data-toggle="" data-target="" class="btn categories-btn" (click)="getArticlesByCategory(c.id)">
            {{subgroup.title | uppercase}}
          </button>
        </li>
    </ul>
  </div>
</div>

如您所见,getArticlesByCategory 方法的位置如下:(click)="getArticlesByCategory(c.id) 因此,当用户点击每个类别时,都会调用此方法:

getArticlesByCategory(selectedCategoryId: string) {
this._articleService.getArticlesByCategory(selectedCategoryId).subscribe(articles => {
  this.category= category;
});

文章被提取了,我试过console.log 他们在那里..

这是我的第二个组件,应该显示该文章:

import { Component, OnInit, Input } from '@angular/core';
import { Article } from '../../models/article';

@Component({
  selector: 'app-main-article',
  templateUrl: './article.component.html',
  styleUrls: ['./article.component.css']
})
export class ArticleComponent implements OnInit {

// Here I've created `@Input` because I think it needs to receive this list of articles

 @Input() category: Article[];
 constructor() { }

  ngOnInit() {
  }
}

这是我的组件的模板文件,应该接收和显示文章:

<div *ngFor="let product of products ;" class="article-holder">
  <div id="article1" class="article">
     <p class="article-price">product.price</p>
     <p class="article-title">product.title</p>
   </div>
</div>

正如您在我的模板文件中看到的,代码已准备好循环该列表,但我不知道如何获取它,谁能解释一下如何执行此操作?

谢谢 干杯

【问题讨论】:

  • 最好在两个组件中使用共享服务。只有当您将数据从父级传递给子级时,@Input 装饰器才会起作用。
  • 有一个工作的 plunker 演示了如何在对类似问题的回答中做到这一点:stackoverflow.com/a/48368909/7840778
  • @Steveland83 请检查我的编辑。我想出了解决方案,但是每次单击都会执行两次..(检查您提供给我的链接以查看完整代码)这通常是比使用@Input@Output更好的解决方案吗?你能解释一下为什么吗?非常感谢
  • @Roxy'Pro 很难说没有看到完整的代码,但有几件事需要检查:1. 确保您在页面导航等上取消订阅您的 observables。2. 是否有多个具有此逻辑的组件(或重复一个组件)? - 如果是这样,那么您需要区分每个组件并发送带有参数的调用。
  • @Steveland83 我怎样才能检查这个:“确保你在页面导航等上取消订阅你的观察。”去哪里看?我还不太明白这个:/

标签: angular typescript angular-components angular-decorator


【解决方案1】:

有多种方法可以将数据从一个组件发送到另一个组件。我建议尝试一项服务

ng generate service article.service.ts

然后使用该服务在两者之间共享数据

看起来像这样:

组件 1: componentOneData: 任意;

constructor(private articleService: ArticleService) {}

ngOnInit() {
  getData() {
    const data = http.get....
    this.articleService.data = data;
    this.componentOneData = data;
  }
}

组件 2:

componentTwoData: any;

constructor(private articleService: ArticleService) {}

ngOnInit() {
  this.data = this.articleService.data; // Now I can access the data
}

服务:

@Injectable()
export class ArticleService {
  data: any;
}

因此,该服务只是帮助在两个组件之间共享数据。您基本上是将数据存储在服务中,以便多个组件可以访问它。

【讨论】:

  • 您能否至少提供一个示例来说明如何将数据添加到服务中?
  • 当然,我添加了它
  • 您的第二个组件没有重新加载,这就是您的模板没有更新的原因,最好将按钮 id 从第一个组件传递到第二个组件,在第二个组件内部调用您各自的服务
  • @LaxmipriyaDas 它的真实模板没有更新,你有什么建议?
  • 我的建议是将这个 (getArticlesByGroupId(g.id)) 特定按钮 id 传递给第二个组件,在第二个组件调用 servicegetArticlesByGroupId(selectedCategoryId: string) { this._articleService.getArticlesByGroupId(selectedCategoryId).subscribe(文章 => { this.articles = 文章; });
【解决方案2】:

您可以使用具有一个实例的 Singleton 服务,在其中输入一些日期,然后在您需要的任何地方获取它们。 创建一个共享模块,然后创建一个 sharedService 并将您的共享模块导入您的主模块和仪表板模块中

您可以使用 ModuleWithProviders 和 forRoot 来提供单例服务

import { SharedService } ...
...
export class SharedModule {
static forRoot(): ModuleWithProviders {
    return {
        ngModule: SharedModule,
        providers: [SharedService]
    }
}}

你可以这样导入:

imports: [
    SharedModule.forRoot(),
],

参考

https://angular-2-training-book.rangle.io/handout/modules/shared-modules-di.html

【讨论】:

  • 此服务可用于从数据库中获取数据,也可用于共享数据,还是应该是两个独立的服务?一种用于数据共享,一种用于从数据库中获取项目?
  • 你可以使用发射功能。
【解决方案3】:

通过如下服务传递可能是个好主意:

@Injectable()
export class CategoryService {
    categoryEmitter: EventEmitter<any> = new EventEmitter();

    // you can add function and data
}

将其导入您的模块和组件中:

//Module
   providers:[SearchService]
//component
constructor(private catService : CategoryService ){}

并呼吁改变 =>

this.catService.categoryEmitter.emit(data);

并订阅你需要监听变化的组件(中间组件)=>

this.catService.categoryEmitter.subscribe((data)=>{
     // logic
});

见:https://angular.io/tutorial/toh-pt4

希望对你有帮助!

【讨论】:

  • 是否应该将其作为数据共享的单独服务,或者我可以在通常从数据库中获取数据的同一服务中编写此逻辑?
  • 可能在同一个服务中
猜你喜欢
  • 2019-10-29
  • 2023-02-04
  • 1970-01-01
  • 2021-06-08
  • 1970-01-01
  • 2021-06-30
  • 2016-04-20
  • 2020-05-07
  • 2023-01-09
相关资源
最近更新 更多