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

时间:2014-09-02 23:02:51

标签: dart polymer dart-polymer

我有:

my-app
  community-list

在附加时,my-app获取用户并加载app.user。在此期间,附加了社区列表(甚至在加载app.user之前),因此我还无法获得用户的已加星标的社区。因此,我正在研究的解决方案如下。

在community-list.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([]);

最初填充在community-list.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 个答案:

答案 0 :(得分:1)

1) toList()创建列表的副本。您需要再次应用toObservable才能获得可观察的列表。

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

这也为communities分配了@observable所涵盖的新列表。 我认为它应该触发

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

的方法
if (app.user != null) {
  getUserStarredCommunities();
}
每次更改列表时都会显式

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

使用app.changes.listen,您可以收听组件中任何@observable字段的更新内容。如果communities旁边有其他可观察字段,则此方法可能会被调用太频繁。 如果您只对communities的更改感兴趣,则应将此代码放入类似

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

但更好的选择是不听取更改和其他方法名称,并在可能的情况下将其明确地称为上述状态。