代码之家  ›  专栏  ›  技术社区  ›  David Notik

为什么我更新的可观察列表没有反映在模板中?

  •  1
  • David Notik  · 技术社区  · 10 年前

    我有:

    my-app
      community-list
    

    在附件中,我的应用程序获取用户并加载app.user。同时,社区列表已附加(甚至在app.user加载之前),因此我还无法获取用户的星级社区。因此,我正在研究的解决方案如下。

    在社区列表.attached()中:

    app.changes.listen((List<ChangeRecord> records) {
      if (app.user != null) {
        getUserStarredCommunities();
      }
    });
    

    社区列表中的其他地方称为方法:

      // This is triggered by an app.changes.listen.
      void getUserStarredCommunities() {
        // Determine if this user has starred the community.
        communities.forEach((community) {
          var starredCommunityRef = new db.Firebase(firebaseLocation + '/users/' + app.user.username + '/communities/' + community['id']);
          starredCommunityRef.onValue.listen((e) {
            if (e.snapshot.val() == null) {
              community['userStarred'] = false;
            } else {
              community['userStarred'] = true;
            }
          });
        });
      }
    

    注意,社区是社区列表中的一个可观察列表:

    @observable List communities = toObservable([]);
    

    最初填充在社区列表.attached()中:

    getCommunities() {
        var f = new db.Firebase(firebaseLocation + '/communities');
    
        var communityRef = f.limit(20);
        communityRef.onChildAdded.listen((e) {
          var community = e.snapshot.val();
    
          // If no updated date, use the created date.
          if (community['updatedDate'] == null) {
            community['updatedDate'] = DateTime.parse(community['createdDate']);
          }
    
          // snapshot.name is Firebase's ID, i.e. "the name of the Firebase location"
          // So we'll add that to our local item list.
          community['id'] = e.snapshot.name();
    
          // Insert each new community into the list.
          communities.add(community);
    
          // Sort the list by the item's updatedDate, then reverse it.
          communities.sort((m1, m2) => m1["updatedDate"].compareTo(m2["updatedDate"]));
          communities = communities.reversed.toList();
        });
      }
    

    总之,我甚至在有用户之前就加载了社区列表,但一旦有了用户,我就想用userStarred=true/false更新社区列表中的每个社区(Map),然后在社区列表模板中使用。

    1. 唉,列表似乎没有更新。我如何做到这一点?
    2. 整个app.changes.listen业务非常昂贵。在这样的情况下,在我加载对象(如app.user)之前加载一个元素,该对象将以某种方式对其进行修改,这是正确的做法。
    1 回复  |  直到 10 年前
        1
  •  1
  •   Günter Zöchbauer    10 年前

    1) toList() 创建列表的副本。你需要申请 toObservable 再次获得可观察列表。

    communities = toObservable(communities.reversed.toList());
    

    这也会将新列表分配给 communities @observable . 我想无论如何都应该触发

    2) 您可以明确更新您的社区。应该没有必要倾听 changes 。您可以调用包含

    if (app.user != null) {
      getUserStarredCommunities();
    }
    

    每次更改列表时都会显式地显示。

    您还可以在发生更改时为每个社区调用Firebase 社区 发生。我不知道Firebase,但似乎每次都会向服务器发送请求,这当然很昂贵。 你应该记住什么 user + community 组合您已经拨打了电话,并改用记住的结果。

    具有 app.changes.listen 您可以收听任何更新的 @可观察的 字段。如果旁边有其他可观察的字段 社区 此方法可能调用得太频繁。 如果您只对以下内容的更改感兴趣 社区 您应该将此代码放入如下方法

    communitiesChanged(oldVal, newVal) {
      if (app.user != null) {
        getUserStarredCommunities();
      }
    }
    

    但更好的选择是不监听更改和另一个方法名,并在可能的情况下将其显式调用为上面的状态。