2014-09-02 64 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

相關問題