angular - 在 AngularDart 中正确使用流
问题描述
我在使用 Streams 更新我的视图时遇到了困难。
目前有一个显示所有帖子的视图,以及一个创建帖子的表单。提交帖子后,aconsole.log()
会显示新创建的帖子,但视图不会呈现它。这很可能是对流的滥用。
这是当前代码
post_create_component.dart
:
class PostCreateComponent {
final PostListService postListService;
PostCreateComponent(this.postListService);
onAddPost(NgForm form) {
Post post = Post(form.value["title"], form.value["content"]);
this.postListService.addPost(post);
}
}
post_list_component.dart
class PostListComponent implements OnInit, OnDestroy {
final PostListService postListService;
StreamSubscription<List<Post>> _postsSubscription;
List<Post> postList = [];
PostListComponent(this.postListService);
@override
ngOnInit() {
this.postList = this.postListService.getPostList();
this._postsSubscription = this
.postListService
.getPostUpdateListener
.listen((List<Post> posts) => this.postList = posts);
}
ngOnDestroy() {
_postsSubscription.cancel();
}
}
post_list_service.dart
@Injectable()
class PostListService {
List<Post> _postList = <Post>[Post("hello", "world")];
final _postUpdated = new StreamController<List<Post>>();
List<Post> getPostList() {
return List.from(this._postList);
}
@Output()
Stream<List<Post>> get getPostUpdateListener {
return _postUpdated.stream;
}
addPost(Post post) {
this._postList.add(post);
this._postUpdated.add(List.from(this._postList));
window.console.log(List.from(this._postList));
}
}
并console.log
显示以下内容:
(2) [s…l.P…t.new, s…l.P…t.new]
0: src__post_model.Post.new {Symbol(Post.title): "hello", Symbol(Post.content): "world"}
1: src__post_model.Post.new {Symbol(Post.title): "world", Symbol(Post.content): "hello"}
length: 2
Symbol(dartx.first): (...)
Symbol(dartx.hashCode): (...)
Symbol(dartx.isEmpty): (...)
Symbol(dartx.isNotEmpty): (...)
Symbol(dartx.iterator): (...)
Symbol(dartx.last): (...)
Symbol(dartx.length): (...)
Symbol(dartx.reversed): (...)
Symbol(dartx.runtimeType): (...)
Symbol(dartx.single): (...)
__proto__: Array
任何意见是极大的赞赏。
更新
所以我的post_list_component.html
, post_create_component.html
,app_component.html
文件如下:
post_list_component.html
<section *ngIf="postList.isNotEmpty">
<material-expansionpanel *ngFor="let post of postList" name="{{post.title}}" [showSaveCancel]="false">
{{post.content}}
</material-expansionpanel>
</section>
<material-expansionpanel *ngIf="postList.isEmpty" name="No messages" [showSaveCancel]="false" disabled>
No Messages :(
</material-expansionpanel>
post_create_component.html
这个组件可能需要修复,但现在我想首先专注于正确实现
<section class="data-entry">
<h2>Post Comments</h2>
<div class="mdc-card demo-size">
<form #postForm="ngForm" (ngSubmit)="onAddPost(postForm)">
<material-input
autoFocus
label="Title"
floatingLabel
class="wide"
ngControl="title"
required
name="title"
ngModel
#title
requiredErrorMsg="Enter a title"
>
</material-input>
<material-input
label="Content"
floatingLabel
class="wide"
ngControl="content"
required
name="content"
ngModel
#content
requiredErrorMsg="Enter a message"
>
</material-input>
<div class="mdc-card__actions">
<div class="mdc-card__action-buttons">
<material-button
raised
type="submit"
[disabled]="!postForm.form.valid"
(trigger)="onAddPost(postForm)"
>Save Post</material-button
>
</div>
</div>
</form>
</div>
</section>
app_component.html
<app-header></app-header>
<div class="app-body">
<app-post-create></app-post-create>
<app-post-list></app-post-list>
</div>
更新 2
app_component.dart
@Component(
selector: 'my-app',
styleUrls: ['app_component.css'],
templateUrl: 'app_component.html',
directives: [PostCreateComponent, PostListComponent, HeaderComponent],
providers: [ClassProvider(PostListService), materialProviders],
)
class AppComponent {}
解决方案
您不应在服务中使用 @Output 注释,正确的代码应如下所示:
@Injectable()
class PostListService {
final _postUpdated = StreamController<List<Post>>.broadcast();
final _postList = [Post("hello", "world")];
Stream<List<Post>> get postUpdated => _postUpdated.stream;
List<Post> get postList => _postList.toList();
void addPost(Post post) {
_postList.add(post);
_postUpdated.add(_postList.toList());
window.console.log(_postList.toList());
}
}
在组件中:
class PostListComponent implements OnInit, OnDestroy {
final PostListService _postListService;
StreamSubscription<List<Post>> _postsSubscription;
List<Post> postList = [];
PostListComponent(this.postListService);
@override
void ngOnInit() {
postList = this.postListService.postList;
_postsSubscription = _postListService.postUpdated
.listen((posts) => postList = posts);
}
@override
void ngOnDestroy() {
_postsSubscription.cancel();
}
}
与主题无关,我建议查看 Dart 和 Angular 样式指南 - https://www.dartlang.org/guides/language/effective-dart
推荐阅读
- dart - 我如何在 Dart 中解码?
- javascript - JSON对象循环api
- command-line - 我怎样才能获得 P4CLIENT
- javascript - 与容器相比,如何使滚动条的宽度/长度更小
- google-cloud-platform - 使用 Google Cloud 语音转文本仅转录特定部分的音频
- amazon-web-services - AWS EB 多容器 Datadog 集成无法正常工作
- c++ - 如何使用一张地图存储不同的功能
- anchor - 在带有锚标签的手机上的另一个选项卡中打开链接
- python - 有没有办法将 tkinter 中的条目文本框转换为变量
- javascript - 如何访问javascript函数中输入文本字段的值?