当我使用提供程序模式时,在不刷新的情况下更新嵌套页面(而不是小部件树)中的值

时间:2020-06-23 01:19:09

标签: flutter dart provider

我正在以诸如Facebook之类的新闻提要的形式制作应用程序。我想让它的用户浏览feed中的内容,并通过单击feed(feedPagepostPage)使他们阅读更多详细信息。 我将Firestore用作后端和提供程序模式。

feedPage引用StreamProvider和myUserData Provider(来自main.dart) 每当修改或更改内容或单击喜欢的内容,添加评论时,便会立即更新,而无需刷新。

// feed_page.dart

class FeedPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamProvider<List<Post>>.value(
      value: firestoreProvider.fetchAllPosts(),
      child: Scaffold(
        backgroundColor: Colors.grey[200],
        appBar: AppBar(
          automaticallyImplyLeading: false,
          title: GestureDetector(
            child: Text('test'),

-----


  Container _postActions(
      BuildContext context, MyUserData myUserData, Post post) {
    return Container(
      child: Padding(
        padding: const EdgeInsets.fromLTRB(
            common_gap, common_gap, common_gap, common_gap),
        child: Row(
          children: <Widget>[
            GestureDetector(
              onTap: () {
                final route = MaterialPageRoute(
                    builder: (context) => PostPage(myUserData.data, post));
                Navigator.of(context).push(route);
              },


问题出在post_page.dart中。通过导航器访问postPage时,我可以在postPage中看到所有详细信息。但是,当我修改某些内容(例如单击“喜欢/心形按钮”,添加评论)时,postPage中看不到任何更改。

// post_page.dart

class PostPage extends StatefulWidget {
  final User user;
  final Post post;

  const PostPage(this.user, this.post, {Key key}) : super(key: key);

  @override
  _PostPageState createState() => _PostPageState();
}

class _PostPageState extends State<PostPage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey[200],
      appBar: AppBar(
        centerTitle: false,
        elevation: 0,
        actions: <Widget>[
          IconButton(
            icon: Icon(
              Icons.label_outline,
              color: Colors.grey[900],
              size: 30,
            ),
            onPressed: null,
          ),
        ],
      ),
      body: Form(
        key: _formkey,
        child: SafeArea(
          child: Column(
            children: <Widget>[
              Expanded(
                child: CustomScrollView(
                  slivers: <Widget>[
                    SliverToBoxAdapter(
                      child: _postItem(
                          context, widget.post.title, widget.post.content),
                    ),
                    SliverToBoxAdapter(
                      child: _postComments(),
                    ),
                  ],
                ),
              ),
              _commentField()
            ],
          ),
        ),
      ),
    );
  }

  Container _postActions(BuildContext context) {
    return Container(
      child: Padding(
        padding: const EdgeInsets.fromLTRB(
            common_gap, common_gap, common_gap, common_xl_gap),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            GestureDetector(
              onTap: () {},
              child: Row(
                children: <Widget>[
                  Image.asset('assets/comment.png',
                      width: 17, fit: BoxFit.cover),
                  SizedBox(
                    width: common_xxs_gap,
                  ),
                  Text("${widget.post.numOfComments}", // <-------------------------- my issue is here!
                      style: TextStyle(fontSize: 13.0, color: Colors.black87))
                ],
              ),
            ),
)
    );
  }

例如,如果我在此页面中添加了评论,widget.post.numOfComments in PostPage应该立即更新,但是要使其更新,我必须通过回到feedPage并再次返回postPage来刷新它。

我认为这是因为我没有在postPage中设置提供程序或setState。 但是我实际上不知道如何在FirebaseProvider中使用setState。 如果可能的话,我想使用Provider,因为它嵌套在feedPage中(我知道它不在feedPage的小部件树中)。

// firestore_provider.dart

class FirestoreProvider with Transformer {
  final Firestore _firestore = Firestore.instance;

  Future<void> attemptCreateUser({String userKey, String phone}) async {
    final DocumentReference userRef =
        _firestore.collection(COLLECTION_USERS).document(userKey);
    final DocumentSnapshot snapshot = await userRef.get();
    return _firestore.runTransaction((Transaction tx) async {
      if (!snapshot.exists) {
        await tx.set(userRef, User.getMapForCreateUser(userKey, phone));
      }
    });
  }

  Stream<User> connectMyUserData(String userKey) {
    return _firestore
        .collection(COLLECTION_USERS)
        .document(userKey)
        .snapshots()
        .transform(toUser);
  }

  Stream<List<User>> fetchAllUsers() {
    return _firestore
        .collection(COLLECTION_USERS)
        .snapshots()
        .transform(toUsers);
  }

  Future<Map<String, dynamic>> createNewPost(
      String postKey, Map<String, dynamic> postData) async {
    final DocumentReference postRef = _firestore
        .collection(COLLECTION_POSTS)
        .document(postKey); // 없으면 자동으로 Reference 생성됨.
    final DocumentSnapshot postSnapshot = await postRef.get();
    final DocumentReference userRef =
        _firestore.collection(COLLECTION_USERS).document(postData[KEY_USERKEY]);
    return _firestore.runTransaction((Transaction tx) async {
      if (!postSnapshot.exists) {
        await tx.update(userRef, {
          KEY_MYPOSTS: FieldValue.arrayUnion([postKey])
        });
        await tx.set(postRef, postData);
      }
    });
  }

  Stream<List<Post>> fetchAllPosts() {
    return _firestore
        .collection(COLLECTION_POSTS)
        .orderBy(KEY_POSTTIME, descending: true)
        .snapshots()
        .transform(toPosts);
  }

  Future<Map<String, dynamic>> createNewComments(
      String postKey, Map<String, dynamic> commentData) async {

    final DocumentReference postRef = _firestore
        .collection(COLLECTION_POSTS)
        .document(postKey); // 없으면 자동으로 Reference 생성됨.

    final DocumentSnapshot postSnapshot = await postRef.get();
    print(postSnapshot);
    final DocumentReference commentRef =
        postRef.collection(COLLECTION_COMMENTS).document();


    return _firestore.runTransaction((Transaction tx) async {
      if (postSnapshot.exists) {
        await tx.set(commentRef, commentData);
        int numOfComments = postSnapshot.data[KEY_NUMOFCOMMENTS];

        await tx.update(postRef, {KEY_NUMOFCOMMENTS: numOfComments + 1});
      }
    });
  }

  Stream<List<CommentModel>> fetchAllComments(String postKey) {
    return _firestore
        .collection(COLLECTION_POSTS)
        .document(postKey)
        .collection(COLLECTION_COMMENTS)
        .orderBy(KEY_COMMENTTIME)
        .snapshots()
        .transform(toComments);
  }
}

FirestoreProvider firestoreProvider = FirestoreProvider();

请帮助。.谢谢!

0 个答案:

没有答案