Как получить доступ к родительскому компоненту из дочернего компонента в Angular 9 - PullRequest
1 голос
/ 30 марта 2020

Проблема

  • Не удается пользователю viewContainerRef для связи родительского и дочернего.

Код работал в Angular 8,2

 this.viewContainerRef[ '_data' ].componentView.component.viewContainerRef[ '_view' ].component;

Ошибка

ОШИБКА TypeError: Невозможно прочитать свойство 'componentView' из неопределенного

Publi c API https://angular.io/api/core/ViewContainerRef

    this.viewContainerRef.get(0) still i got null

Мне нужен доступ к родительскому компоненту из дочернего компонента.

Ng Версия

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.900.7
@angular-devkit/core         9.0.7
@angular-devkit/schematics   9.0.7
@schematics/angular          9.0.7
@schematics/update           0.900.7
rxjs                         6.5.3

Невозможно воспроизвести проблему в stackblitz

https://stackblitz.com/edit/angular-testangular9-communicating-x

Проблема

ViewContainerRef не работает в Angular 9

Рабочая ViewContainerRef

enter image description here

Не работает ViewConatinerRef в Angular 9 enter image description here

Любые предложения приветствуются.

1 Ответ

2 голосов
/ 01 апреля 2020

Вы не должны ( определенно ) получать доступ к закрытым членам сторонней библиотеки именно для того, чтобы избежать неприятностей, с которыми вы столкнулись. К счастью, если я правильно понял, что вы хотите сделать, вы можете что-то сделать, чтобы избежать доступа к этим частным пользователям. Я покажу 3 решения, 2 из которых реализованы на стеке, указанном в конце этого ответа.

Предположим, у вас есть такой сценарий: родительский компонент с propertyA, к которому вы хотите получить прямой доступ в дочернем компоненте по какой-то причине.

Родительский компонент:

@Component({
  template: `
    <child></child>
  `
})
export class ParentComponent { propertyA: string; }

Случай A: инъекция родителя непосредственно в дочерний элемент

@Component({selector: 'child', ...})
export class ChildComp {
  constructor(private _parent: ParentComponent) { this._parent.propertyA = 'some value'; }
}

Случай B: получение родитель через ребенка ViewContainerRef

@Component({selector: 'child', ...})
export class ChildComp {
  constructor(private viewContainerRef: ViewContainerRef) {
    const _injector = this.viewContainerRef.parentInjector;
    const _parent: ParentComponent = _injector.get<ParentComponent>(ParentComponent);  
    this._parent.propertyA = 'some value';
  }
}

Это важная часть: angular инжекторы существуют именно для того, чтобы делать то, что вы хотите, поэтому вместо того, чтобы пытаться получить ссылку на компонент самостоятельно, право Что нужно сделать, это выяснить, как найти инжектор для поиска вас. Помните, что инжекторы распределены в иерархии таким образом, что, если инжектор не может разрешить символ, он просит родительский инжектор попытаться решить его рекурсивно, пока не доберется до инжектора root. Это привело нас к третьему подходу, получающему инжектор компонента напрямую:

Случай C: Проведение родителя через инжектор ребенка, вводимый напрямую

@Component({selector: 'child', ...})
export class ChildComp {
  constructor(private _injector: Injector) { 
    const _parent: ParentComponent = this._injector.get<ParentComponent>(ParentComponent);  
    this._parent.propertyA = 'some value';
  }
}

Случаи B и C работать, потому что ваши компоненты распределены в дереве компонентов в отношении parent-nth-child и в какой-то момент у них будет общий инжектор в модуле, где они объявлены / импортированы.

I ' мы изменили ваш стек , чтобы показать оба этих решения (случай A используется для a-компонента, a случай B используется для b-компонента),

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