问题
Basically I have a timeline with posts that is a $firebaseArray and any change to this array is getting binded properly. But when I want to bind any other data it only binds when ngInfiniteScroll is trying to retrieve more data from firebase, so only when I scroll down.
In the code bellow I'm calling {{getMoreDetails()}}
and this data is binded when the first set of data is being retrieved with ngInfiniteScroll but as soon as it is loaded the bind breaks and only binds again when scrolling.
My concerns here are:
- Was ngInfiniteScroll designed to work this way?
- Is there any workaround in this scenario?
Stack:
"firebase": "2.4.2","angularfire": "~1.2.0","firebase-util": "0.2.5","ngInfiniteScroll": "1.2.2"
timeline.html
<div ng-controller="TimelineController">
<section class="entrys main-content" infinite-scroll="posts.scroll.next(3)" infinite-scroll-distance="0.3">
<div class="inner">
<div ng-repeat="post in filteredPostsResults = (posts | filter:postIdFilter)">
<article class="entry">
<img ng-if="post.sourceType=='IMAGE'" data-ng-src="{{getPostData(post)}}"/>
<div class="entry-info">
<h3><div ng-bind-html="post.description | emoticons"></div></h3>
<small>posted on <time>{{getDateInFormat(post.createdAt)}}</time></small>
{{getMoreDetails()}}
</div>
</article>
</div>
</div>
</section>
</div>
timeline.js
(function (angular) {
"use strict";
var timeline = angular.module('myApp.user.timeline', ['firebase', 'firebase.utils', 'firebase.auth', 'ngRoute', 'myApp.user.timelineService']);
timeline.controller('TimelineController', [ '$scope', '$routeParams', 'TimelineService', '$publisherServices', '$securityProperties', function ($scope, $routeParams, TimelineService, $publisherServices, $securityProperties) {
if (!$scope.posts){
$scope.posts = TimelineService.getPosts($routeParams.userId);
}
$scope.posts.$loaded(function(result) {
$scope.isPostsLoaded = true;
});
$scope.getMoreDetails = function() {
console.log("LOGGED ONLY WHEN SCROLLING");
return $publisherServices.getDetails();
};
$scope.getPostData = function(post) {
if (!post.dataUrl){
post.dataUrl = $publisherServices.getAwsFileUrl(post.fileName);
}
return post.dataUrl;
};
$scope.postIdFilter = function(post) {
if ($routeParams.postId){
if (post.$id == $routeParams.postId) return post;
} else { return post; }
};
$scope.getDateInFormat = function(timestamp){
var date = new Date();
date.setTime(timestamp);
return date;
};
}]);
})(angular);
timelineService.js
(function (angular) {
"use strict";
var timelineService = angular.module('myApp.user.timelineService', []);
timelineService.service('TimelineService', ['$routeParams', 'FBURL', '$firebaseArray', function ($routeParams, FBURL, $firebaseArray) {
var posts;
var currentUserIdPosts;
var postsRef;
var self = {
getPosts: function(userId){
if (!posts || userId != currentUserIdPosts){
currentUserIdPosts = userId;
postsRef = new Firebase(FBURL).child("posts").child(userId);
var scrollRef = new Firebase.util.Scroll(postsRef, "createdAtDesc");
posts = $firebaseArray(scrollRef);
posts.scroll = scrollRef.scroll;
}
return posts;
}
}
return self;
}]);
})(angular);
回答1:
I am assuming that you want the post details updated when the data from your Firebase changes.
When Firebase changes are applied to your scope, it seems that it doesn't trigger a digest cycle, so you probably need to do it manually every time you get updates from Firebase.
Take a look at $$updated
in $firebaseArray.$extend
(see docs).
// now let's create a synchronized array factory that uses our Widget app.factory("WidgetFactory", function($firebaseArray, Widget) { return $firebaseArray.$extend({ // override the update behavior to call Widget.update() $$updated: function(snap) { // we need to return true/false here or $watch listeners will not get triggered // luckily, our Widget.prototype.update() method already returns a boolean if // anything has changed return this.$getRecord(snap.key()).update(snap); } }); });
I hope this helps.
来源:https://stackoverflow.com/questions/37511169/angular-binding-not-working-properly-with-nginfinitescroll