이것이 내가 Firebase 데이터 스토어에서 실시간으로 주연/좋아하는 (커뮤니티의 경우) 작업을 수행하게 된 원인입니다. 그것은 엉망이고 확실하게 나는 몇몇 근본을 놓치고있다.관찰 목록 및지도, Firebase, 오 마이. 이 혼란을 어떻게 개선 할 수 있습니까?
여기 내 요소는 각각 Map community
으로 표시된 List communities
에 저장된 커뮤니티를 가져옵니다. 여기
getCommunities() {
// Since we call this method a second time after user
// signed in, clear the communities list before we recreate it.
if (communities.length > 0) { communities.clear(); }
var firebaseRoot = new db.Firebase(firebaseLocation);
var communityRef = firebaseRoot.child('/communities');
// TODO: Undo the limit of 20; https://github.com/firebase/firebase-dart/issues/8
communityRef.limit(20).onChildAdded.listen((e) {
var community = e.snapshot.val();
// 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();
print(community['id']);
// If the user is signed in, see if they've starred this community.
if (app.user != null) {
firebaseRoot.child('/users/' + app.user.username + '/communities/' + community['id']).onValue.listen((e) {
if (e.snapshot.val() == null) {
community['userStarred'] = false;
// TODO: Add community star_count?!
} else {
community['userStarred'] = true;
}
print("${community['userStarred']}, star count: ${community['star_count']}");
// Replace the community in the observed list w/ our updated copy.
communities
..removeWhere((oldItem) => oldItem['alias'] == community['alias'])
..add(community)
..sort((m1, m2) => m1["updatedDate"].compareTo(m2["updatedDate"]));
communities = toObservable(communities.reversed.toList());
});
}
// If no updated date, use the created date.
if (community['updatedDate'] == null) {
community['updatedDate'] = community['createdDate'];
}
// Handle the case where no star count yet.
if (community['star_count'] == null) {
community['star_count'] = 0;
}
// The live-date-time element needs parsed dates.
community['updatedDate'] = DateTime.parse(community['updatedDate']);
community['createdDate'] = DateTime.parse(community['createdDate']);
// Listen for realtime changes to the star count.
communityRef.child(community['alias'] + '/star_count').onValue.listen((e) {
int newCount = e.snapshot.val();
community['star_count'] = newCount;
// Replace the community in the observed list w/ our updated copy.
// TODO: Re-writing the list each time is ridiculous!
communities
..removeWhere((oldItem) => oldItem['alias'] == community['alias'])
..add(community)
..sort((m1, m2) => m1["updatedDate"].compareTo(m2["updatedDate"]));
communities = toObservable(communities.reversed.toList());
});
// 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 = toObservable(communities.reversed.toList());
});
}
우리가 다시 대체 별을 전환 : 그것은 변경된 별의 결과에 따라 각 지역 사회지도 카운트 변경하고 사용자의 별표 상태 및 다른 재미로 그 목록을 여러 번 재 작성해야 우리가 영향을받는 지역 사회지도의 수를 업데이트하고, 따라서 그것을 반영하기 위해 목록을 다시 작성으로 관찰 된 지역 사회는 몇 번 나열
toggleStar(Event e, var detail, Element target) {
// Don't fire the core-item's on-click, just the icon's.
e.stopPropagation();
if (app.user == null) {
app.showMessage("Kindly sign in first.", "important");
return;
}
bool isStarred = (target.classes.contains("selected"));
var community = communities.firstWhere((i) => i['id'] == target.dataset['id']);
var firebaseRoot = new db.Firebase(firebaseLocation);
var starredCommunityRef = firebaseRoot.child('/users/' + app.user.username + '/communities/' + community['id']);
var communityRef = firebaseRoot.child('/communities/' + community['id']);
if (isStarred) {
// If it's starred, time to unstar it.
community['userStarred'] = false;
starredCommunityRef.remove();
// Update the star count.
communityRef.child('/star_count').transaction((currentCount) {
if (currentCount == null || currentCount == 0) {
community['star_count'] = 0;
return 0;
} else {
community['star_count'] = currentCount - 1;
return currentCount - 1;
}
});
// Update the list of users who starred.
communityRef.child('/star_users/' + app.user.username).remove();
} else {
// If it's not starred, time to star it.
community['userStarred'] = true;
starredCommunityRef.set(true);
// Update the star count.
communityRef.child('/star_count').transaction((currentCount) {
if (currentCount == null || currentCount == 0) {
community['star_count'] = 1;
return 1;
} else {
community['star_count'] = currentCount + 1;
return currentCount + 1;
}
});
// Update the list of users who starred.
communityRef.child('/star_users/' + app.user.username).set(true);
}
// Replace the community in the observed list w/ our updated copy.
communities.removeWhere((oldItem) => oldItem['alias'] == community['alias']);
communities.add(community);
communities.sort((m1, m2) => m1["updatedDate"].compareTo(m2["updatedDate"]));
communities = toObservable(communities.reversed.toList());
print(communities);
}
우리가 때 응용 프로그램을 다시 지역 사회의 목록을 얻을 수있는 다른 막무가내도있다 .changes 왜냐하면 우리는 앱과리스트 초기에 app.user를로드하기 만하기 때문이다. 그리고 이제 우리는 우리가 필요로하는 사용자를 가지고있다. 적절한 별을 켭니다. 그래서 내 첨부()과 같습니다
attached() {
app.pageTitle = "Communities";
getCommunities();
app.changes.listen((List<ChangeRecord> records) {
if (app.user != null) {
getCommunities();
}
});
}
이, 내가 그냥 별을 받고있을 수 및 업데이트가 영향을받는 각 지역 사회지도 한 후 관찰 된 커뮤니티 목록을 다시 채우기 말했다 보인다, 그러나 그것은 그것의 이상입니다.
전체 일 : https://gist.github.com/DaveNotik/5ccdc9e74429cf87d641
- 나는이 모든지도/목록 관리를 향상시킬 수있는 방법
, 예를 들어, 커뮤니티지도를 변경할 때마다 전체 커뮤니티 목록을 다시 작성해야합니까? 나는 그것을 다르게 생각해야 하는가?
이 모든 Firebase 쿼리는 어떻게됩니까? 확실히 더 좋은 방법이 있지만, 실시간으로 유지하려면 많은 작업이 필요하고, 요소가 연결되고 분리되기 때문에 매번 getCommunities()를 실행해야합니다. OOP 방식으로 객체를 만들지 않으면 요소가 첨부 될 때마다 항상 관찰해야합니다. 나는 그 기초를 놓치고있다.
이 app.user는 app.user (우리는 별을로드하려고 함)를 갖기 전에 목록을로드하는 경우를 처리합니다. 더 나은 방법이 있습니까?
기타 어리석은가요?
큰 질문입니다. 제가 앞으로 나아갈 때 올바른 접근법을 다룰 수 있도록 도와 주셔서 감사합니다!
응용 프로그램의 전체적인 그림을 설명해 주시겠습니까? 사용자의 관점에서 어떻게 작동해야하며 여러 사용자가 동시에 앱을 사용하는 동안 어떤 일이 일어나야합니다. – grohjy
예. 사람들이 참여하고 항목을 게시 할 수있는 커뮤니티. 항목은 여러 커뮤니티에 살 수 있습니다. 사용자는 커뮤니티와 항목에 별표를 표시하고 좋아할 수 있습니다. 모든 항목이 실시간이므로 아이템을 좋아하니 연결된 모든 클라이언트의 업데이트 된 수를 반영해야합니다. 여러 곳에서 로그인 한 경우 별표는 로그인 한 모든 곳에서 반영되어야합니다. 아이디어를 얻으려면 http://mycommunity.org를 참조하십시오. –