Доброе утро,
У меня проблема при загрузке списка из firebase и отображении его в моем виде с AngularFire2.
Пояснения:
У меня на страницефункция, позволяющая загрузить список сообщений и сопоставить сообщения с пользовательскими данными, чтобы затем связать весь список с представлением:
Timeline.ts:
// Get the timeline data
getTimeline() {
console.log('Get timeline data');
this.loadingProvider.show();
this.createUserData(); // create user data if accoutn just created
this.dataProvider.getCurrentUser().valueChanges().subscribe((user) => {
this.user = <any>user;
});
this.getUserFriends().then((friends) => {
this.friends = friends;
}).then(() => {
this.dataProvider.getTimelinePost().valueChanges().subscribe((posts) => {
console.log("Change in timeline");
this.timelineData = posts.slice(0).reverse().map(p => {
return this.checkPostData(p);
});
this.loadingProvider.hide();
});
});
}
// Get the friend's user so we can display only the post who are relevants for the user
getUserFriends() {
return new Promise((resolve) => {
this.dataProvider.getFriends().valueChanges().subscribe((f) => {
resolve(f)
});
});
}
// Map post data with user's info such as avatar, etc
checkPostData(currentPost) {
let postedByFriend = this.checkIfPostedByFriend(currentPost);
if (postedByFriend || currentPost.postBy === firebase.auth().currentUser.uid) {
this.dataProvider.getUser(currentPost.postBy).valueChanges().subscribe((user) => {
currentPost.avatar = user.img;
currentPost.name = user.name
});
// Liked ?
this.dataProvider.getLike(currentPost.key).valueChanges().subscribe((likes) => {
currentPost.likes = likes.length;
currentPost.isLike = this.checkIfPostIsLiked(likes);
});
// Disliked ?
this.dataProvider.getdisLike(currentPost.key).valueChanges().subscribe((dislikes) => {
currentPost.dislikes = dislikes.length;
currentPost.isdisLike = this.checkIfPostIsDislike(dislikes);
});
// Commented ?
this.dataProvider.getComments(currentPost.key).valueChanges().subscribe((comments) => {
currentPost.comments = comments.length;
currentPost.isComment = this.checkIfPostIsCommented(comments);
});
}
return currentPost;
}
Временная шкала.html:
<ion-card *ngFor="let item of timelineData">
<ion-item >
<ion-avatar item-left>
<img src="{{item.avatar}}" >
</ion-avatar>
<h2>{{item.name}}</h2>
<p>{{item.dateCreated | DateFormat}}</p>
</ion-item>
<ion-card-content>
<p>{{item.postText}}</p>
</ion-card-content>
[...]
</ion-card>
DataProvider.ts:
// Get Timeline post
getTimelinePost(){
return this.angularDb.list<any>('/timeline');
}
Моя проблема заключается в следующем: когда я добавляю сообщение на временную шкалу, это занимает несколько секунд, поскольку Timeline.tsстраница перезагружает весь список (что является нормальным, потому что есть подписка, сделанная с помощью getTimeLinePost ()).Я хотел бы знать, возможно ли обнаружить только последние изменения в моем списке, чтобы добавить их в представление и, таким образом, избежать перезагрузки всех данных.
Я уже пробовал SnapshotChanges () и StateChange (), но безуспешно.
Я заметил, что когда я добавляю сообщение, подписка срабатывает дважды:
Изменение временной шкалы (2) timeline.ts: 89: 8
Код Addpost.ts:
pushNewPost(url) {
this.angularDb.list('timeline').push({
dateCreated: new Date().toString(),
postBy: firebase.auth().currentUser.uid,
postText: this.postText,
image: url
})
}
Используемые версии: "@angular": "5.2.11", "angularfire2": "^ 5.0.0-rc.5-next",
Есть идеи для этого?Я что-то упустил?
спасибо заранее
ОБНОВЛЕНИЕ:
Я нашел альтернативу, которая оказывает меньшее влияние на производительность рендеринга (на представление), но все данные все ещезагружается при изменении в базе данных:
getTimeline() {
console.log('Get timeline data');
this.loadingProvider.show();
this.createUserData();
this.dataProvider.getCurrentUser().valueChanges().subscribe((user) => {
this.user = <any>user;
});
this.getUserFriends().then((friends) => {
this.friends = friends;
}).then(() => {
this.dataProvider.getTimelinePost().snapshotChanges().map(actions =>
actions.map(a => ({ type: a.type, ...a.payload.val() }))
).subscribe(items => {
this.checkPostData(items);
this.loadingProvider.hide();
});
});
}
getUserFriends() {
return new Promise((resolve) => {
this.dataProvider.getFriends().valueChanges().subscribe((f) => {
resolve(f)
});
});
}
checkPostData(currentPost) {
// Check if whe have a child added to the timeline
if (this.timelineLoaded === true) {
currentPost.forEach(p => {
if (p.type === 'child_added') {
this.mapPost(p);
}
});
} else {
this.timelineData = [];
currentPost.map(p => {
return this.mapPost(p);
});
}
}
mapPost(currentPost) {
let postedByFriend = this.checkIfPostedByFriend(currentPost);
if (postedByFriend || currentPost.postBy === firebase.auth().currentUser.uid) {
this.dataProvider.getUser(currentPost.postBy).valueChanges().subscribe((user) => {
currentPost.avatar = user.img;
currentPost.name = user.name
});
// Liked ?
this.dataProvider.getLike(currentPost.key).valueChanges().subscribe((likes) => {
currentPost.likes = likes.length;
currentPost.isLike = this.checkIfPostIsLiked(likes);
});
// Disliked ?
this.dataProvider.getdisLike(currentPost.key).valueChanges().subscribe((dislikes) => {
currentPost.dislikes = dislikes.length;
currentPost.isdisLike = this.checkIfPostIsDislike(dislikes);
});
// Commented ?
this.dataProvider.getComments(currentPost.key).valueChanges().subscribe((comments) => {
currentPost.comments = comments.length;
currentPost.isComment = this.checkIfPostIsCommented(comments);
});
this.timelineData.unshift(currentPost);
this.timelineLoaded = true
}
return currentPost;
}