Одним из основных преимуществ NgRx является облегчение взаимодействия компонентов. В следующем случае возникает вопрос, как лучше всего обмениваться данными:
<div *ngIf=" content$ | async as content">
<h1>{{content.prop1}}</h1>
<app-component2></app-component2>
</div>
В этом случае мы должны использовать @input
, чтобы отправить content
вниз в app-component2
, или лучше ввести магазин в component2
и снова использовать канал async
?
Что делает app-component2
?
Здравствуйте, @rezanikfal. Я бы сказал, что это зависит от app-component2
обязанностей и сложности логики в этом компоненте. В любом случае, в этом случае я бы использовал @Input
привязку данных и не импортировал Store
в оба компонента. Поскольку привязки данных @Input
и @Output
были сделаны для связи между родительским и дочерним компонентами.
Есть несколько подходов к этому. Одна интересная вещь, которую можно сделать, это иметь селектор "viewModel". По сути, это означает, что у вас есть два компонента: один — презентатор, а другой — контейнер. Контейнер выбирает ровно один селектор (вы объединяете все, что вам нужно для конкретного компонента, в один селектор, используя createSelector
), скажем, viewModel$
или vm$
. Вы также можете добавить к нему некоторые побочные эффекты, используя оператор tap
в компоненте, если это необходимо, но обычно это не так. Затем вы передаете его в канал async
, берете его как локальную переменную в шаблоне и передаете его одному или нескольким дочерним компонентам через входные данные. Таким образом, родительский компонент обрабатывает только связь с хранилищем (выбор данных и действия по отправке), а другие компоненты отображают данные. Шаблон выглядит примерно так:
<div *ngIf="vm$ | async as vm" class="search-container">
<app-search-filters [filters]="vm.filters"></app-search-filters>
<app-search-result [results]="vm.results"></app-search-result>
<app-save-search
[selectedFilters]="vm.filters"
[savedSearches]="vm.savedSearches"></app-save-search>
</div>
Это нормальный подход, но он, конечно, зависит от логики и размера компонента. Если у вас есть огромная страница, содержащая несколько компонентов, которые действительно загружены логикой и небольшими взаимосвязями, может быть разумнее внедрить хранилища в эти компоненты и, возможно, использовать в них подход «viewModel». Например, рассмотрим страницу видео на YouTube. Представьте, что вы пишете его с помощью NgRx. У вас есть несколько блоков, таких как само видео, раздел комментариев, предлагаемые видео и так далее. Все эти блоки имеют много логики, характерной только для них, и каждый из них может иметь большие фрагменты нашего хранилища, связанные с ними. Таким образом, в таком случае лучше было бы разбить их на несколько «умных» компонентов, каждый из которых использует подход «viewModel». В более простых сценариях достаточно иметь один контейнер и один (возможно, несколько) компонент презентатора.
И в любом случае, не внедряйте Store
(или любой сервис в этом отношении) в компоненты, которые в основном предназначены для рендеринга пользовательского интерфейса.
Этот вопрос основан на мнении. Тем не менее, я бы сказал «Ввод», если вы сможете сделать ребенка совершенно немым.