在AngularDart中正确使用流

时间:2019-01-06 03:00:16

标签: angular dart angular-dart dart-async

使用Streams更新视图时遇到困难。

当前具有一个显示所有帖子的视图,以及一个用于创建帖子的表单。提交帖子后,console.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.htmlpost_create_component.htmlapp_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 {}

2 个答案:

答案 0 :(得分:0)

您不应在服务中使用@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

答案 1 :(得分:0)

如果将来有人碰到这个问题,那就是在两个组件上都设置了提供程序,这实际上创建了服务本身的新实例。因此,这两个组件之间没有共享相同的服务。解决方案是将提供程序移到组件树中的更高位置。