У меня были следующие настройки:
- Родительский компонент place_component
- дочерний компонент post_new_component
- дочерний компонент post_list_component
Чтобы решить мою проблему, мне пришлось отправить событие не в родительский компонент, а в другой дочерний компонент. Так что @ Output не сработал бы. Я просто подключил EventBus к другому дочернему компоненту.
Таким образом, html родительского компонента вкратце выглядел так:
...
<div><new-post [place]="place"></new-post></div>
<div><list-posts [place]="place"></list-posts></div>
...
Таким образом, дочерний компонент new-post должен уведомить список-записи дочернего компонента, о том, что был добавлен новый пост, и список-публикаций должен повторно извлечь все сообщения, связанные с местом.
post_event.dart (служба шины событий)
Служба Event Bus устанавливается между post_new_component и post_list_component.
Я передаю int в Stream (int id), это сейчас не важно, так как мне нужно только проверить, если событие сработало, вы также можете проанализировать строку, объект или что-то еще, если вам нужно отправить данные с событием.
@Injectable()
class PostEvent {
final StreamController<int> _onEventStream = new StreamController.broadcast();
Stream<int> onEventStream = null;
static final PostEvent _singleton = new PostEvent._internal();
factory PostEvent() {
return _singleton;
}
PostEvent._internal() {
onEventStream = _onEventStream.stream;
}
onEvent(int id) {
_onEventStream.add(id);
}
}
post_new_component.dart
После добавления сообщения выполняется _postEvent.onEvent (1). Как объяснено выше, «1» не важен, так как я только хочу знать, было ли инициировано событие.
@Component(
selector: 'new-post',
directives: [coreDirectives,
formDirectives,
FileUploader,
materialInputDirectives,
MaterialButtonComponent],
templateUrl: 'post_new_component.html',
styleUrls: ['post_new_component.css'],
providers: [ClassProvider(PostService), ClassProvider(PostEvent)]
)
class PostNewComponent {
final PostService _postService;
final PostEvent _postEvent;
String postText;
Post post;
@Input()
Place place;
PostNewComponent(this._postService, this._postEvent);
// Save a new post
Future<void> save() async {
// Create a new post and then fire a post event to notify the post list component to update itself.
await _postService.create(postText,place.id).then(((_) => _postEvent.onEvent(1)));
}
}
post_list_component.dart
Я настраиваю прослушиватель событий в конструкторе компонента, который прослушивает изменения событий из нового компонента. При каждом получении события я извлекаю все сообщения с помощью функции _getPosts ().
@Component(
selector: 'list-posts',
directives: [coreDirectives, formDirectives],
templateUrl: 'post_list_component.html',
styleUrls: ['post_list_component.css'],
providers: [ClassProvider(PostService), ClassProvider(PostEvent)]
)
class PostListComponent implements OnInit {
final PostService _postService;
final PostEvent _postEvent;
List<Post> posts;
@Input()
Place place;
PostListComponent(this._postService, this._postEvent) {
// listen for postEvents, if received re-fetch posts
_postEvent.onEventStream.listen((int id) => _getPosts());
}
// Get all posts when page loads the first time
void ngOnInit() => _getPosts();
// Function to get all the posts related to a place
Future<void> _getPosts() async {
posts = await _postService.getPostsByPlace(place.id);
}
}
Если кто-нибудь знает лучший способ сделать это, во что бы то ни стало поправьте меня, так как я еще не настолько знаком с фреймворком, и мне трудно понять концепции. Документация охватывает многое, но если кто-то совершенно новичок в фреймворке, например я, мне не хватает некоторой информации. Было бы полезно расширить документацию по Hero, которая охватывает более сложные темы, такие как общение между дочерними компонентами и от дочернего элемента к родительскому, но не уверен, если это где-то объясняется, и я просто пропустил это.