在“孙子元素”和“父元素”之间传递值

时间:2019-11-21 13:11:57

标签: angular angular8

使用Angular 8我有一些组件,如下所示:

Parent 1 > Child 1 > ... > N Grandchild 1 

Parent 2 > Child 2 > ... > N Grandchild 2

Child XN Grandchild X之间可能还有其他组件。因此可以超过3个级别。

客观
1.在N Grandchild 1中设置一个值,然后在Parent 1中使用它。
2.在N Grandchild 2中设置一个值,然后在Parent 2中使用它。

我正在考虑几种选择:

  1. 使用事件发射器(StackBlitz example

    问题:在孙子与父母之间无法正常工作。

    它似乎只能在一个级别上工作...可以使其在N个级别上工作吗?

    export class GrandchildComponent implements OnInit {
    
      @Output() changeEvent = new EventEmitter<string>();
    
      ngOnInit() {
        this.changeEvent.emit('Hello');
      }
    
    } 
    
  2. 使用服务

    在这种情况下,我在N Grandchild X中注入服务来设置值,并在Parent X中注入服务来读取值。

    问题
    如何确保Parent 1读取N GrandChild 1设置的值,而Parent 2读取N GrandChild 2设置的值?这可能吗?

3 个答案:

答案 0 :(得分:1)

就像另一个答案,它提供了使用某种主题的解决方案,但是您遇到的问题是该主题及其价值在应用程序中共享,如果是在根级别提供的。

一种选择是在父级提供服务,这意味着父级及其所有后代具有相同的服务实例,因此,如果grandchild1发出一个值,只有parent1会收到该值,而parent2不会。

因此,如上所述,您将要做的是提供所需的最高级别的服务,在这种情况下,我认为它将是parent

import { MyService } from './my-service';

@Component({
  selector: 'parent',
  template: `
  Parent:
  <p>Value from grandchild: {{value$ | async}}</p>
  <child></child>
  `,
  providers: [MyService] // <<<<<<<<<< add this (only in parent)!
})

export class ParentComponent { 

  value$;

  constructor(private myService: MyService) {
    this.value$ = this.myService.subj$;
  }
}

和服务可能具有:

private subj = new Subject();
public subj$ = this.subj.asObservable();

setValue(value) {
  this.subj.next(value)
}

在孙子中要发出价值时,只需用新值调用setValue()

STACKBLITZ

答案 1 :(得分:0)

您可以尝试在两个组件的注入服务中使用BehaviorSubject,一个组件在BehaviorSubject上侦听。另一个为该主题发出新的价值。

@Injectable({
  providedIn: 'root'
})
export class TestService {

  subject: BehaviorSubject<any>;

  constructor() { 
    this.subject = new BehaviorSubject(null);
  }

  getObservable() {
    return this.subject.asObservable();
  }

  updateValue(value) {
    this.subject.next(value);
  }
}

答案 2 :(得分:0)

第一种方式:您必须在每个级别的链上发出事件,然后只有您才能将事件发送到父组件。

父1(已接收)>孩子1(发出)>孩子2(发出)> N孙子1(发出);

第二种方法:另外,对于服务,您可以在指定from和to时创建消息总线类型的服务。因此,使用这些标志,您可以验证数据的使用地点和对象。

我个人认为您应该采用第一种方法。