Угловой родительский компонент "scoping" дочерний компонент - PullRequest
0 голосов
/ 14 марта 2019

Предположим, у меня есть компоненты Parent и Child.Child может использоваться как автономный компонент или как компонент Parent.Тем не менее, я хочу, чтобы Child имел другое поведение в зависимости от того, где он живет.

Предположим, что Child имеет необязательный @Input [isHappy], который либо true, либо false. Однако , когда компонент Child размещается компонентом Parent, предположим, что isHappy всегда должно быть истинным.

AFAICT Есть два способа сделать это:

1) Пользователь должен просто знать , чтобы всегда указывать [isHappy]="true" всякий раз, когда Child размещается на Parent.

<parent>
  <child [isHappy]="true"></child>
</parent>

2) Parent, устанавливаемых вручнуюthis.child.isHappy = true в пределах ngOnInit ловушки жизненного цикла.

Какой подход предпочтительнее? На мой взгляд, подход №2 имеет больше смысла, пользователям не нужно знать, чтобы установить [isHappy]="true" когда Child размещен Parent.С другой стороны, я знаю, что в Angular не одобряется то, что компоненты программно меняют друг друга, особенно если все компоненты OnPush (пожалуйста, исправьте меня, если я здесь не прав).

Ответы [ 2 ]

0 голосов
/ 14 марта 2019

По моему мнению, 2-й способ будет работать, но это может добавить пару вещей в ваше решение

  1. Плотная связь между двумя компонентами
  2. Что, если parent компонент не имеет child компонента?

Чтобы решить эту проблему лучше, я бы предложил вам использовать декоратор Host, который будет запрашивать зависимость Parent от компонента Child. Если это так, то свойство make isHappy будет true

@Component({...})
export class Child {
   @Input() isHappy: boolean = false;

   constructor(@Optional() @Host() private parent: Parent) {} 

   ngOnInit() {
      // Do only if parent exists
      if (this.parent) {
         this.parent.isHappy = true
      }
   }
} 

Я понимаю, что даже способ, предложенный выше, имеет тесную связь между Parent компонентом. Мы должны подумать об удалении этой зависимости из внутреннего дочернего компонента.

Да, мы можем сделать это небольшим хакерским способом, где мы будем проверять имя непосредственного родительского компонента текущего компонента, как показано ниже. Для достижения того же самого вам нужно было добавить ViewContainerRef зависимость, чтобы получить доступ к родительскому / хостовому компоненту.

constructor(private viewContainer: ViewContainerRef) {}

ngOnInit() {
    if(this.viewContainer[ '_data' ].componentView.parent.component.constructor.name === 'Parent') {
      this.parent.isHappy = true
    }
}
0 голосов
/ 14 марта 2019

Я хочу, чтобы у ребенка было другое поведение в зависимости от того, где он живет.

Как насчет того, чтобы Child компонент знал, где он живет с ElementRef:

export class ChildComponent {
  hasParent: boolean;

  constructor (
    private elRef: ElementRef
  ) {}

  ngOnInit() {
    const el = this.elRef.nativeElement.parentElement as HTMLElement
    this.hasParent = el.localName === 'app-parent'
  }
}

stackblitz: https://stackblitz.com/edit/angular-kagdsu

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...