2014-09-02 24 views
1

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

my-app 
    community-list 

在连接,我的应用程序内获取用户并加载app.user。同时,附加了社区列表(甚至在加载app.user之前),所以我还没有能够获得用户的加星社区。因此,我正在处理的解决方案如下。

在社区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 =真/假的社区的列表更新每个社区(图),然后在我的社区列表模板中使用它。

  1. 唉,它似乎不像列表更新。我如何实现这一目标?
  2. 这整个app.changes.listen业务是昂贵的。在这种情况下,正确的做法是什么?在加载对象(如app.user)之前加载元素,并以某种方式修改它。

回答

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(); 
    } 
} 

但更好的选择是不听的变化和另一种方法的名称,并明确称其为状态上面反正如果可能的话。

+0

toObservable()做到了。超棒的和及时的答案!我会尝试其他的东西,并回来。谢谢! – 2014-09-03 03:01:56

+0

回复:“您可以每次更改列表时明确调用方法。”问题是如果我在getCommunities()中有getUserStarredCommunities(),它仍然会有第一次调用时没有用户的结果。并且一旦用户*被加载,它就不会更新,因为该元素已被连接。如果我离开/分离该元素并回来,它的工作原理,或者如果我这样做app.changes.listen或communitiesChanged技巧。我不明白另一种方式。 – 2014-09-03 03:13:27

+0

我建议不应该改变行为(我不能推断可能影响行为的问题中没有包含的代码)。唯一的影响应该是getUserStarredCommunities可能不经常被调用。 我认为更重要的是不要对'db.Firebase'进行多余的调用,这比遍历集合的代价要昂贵得多。 – 2014-09-03 05:14:49

相关问题