Famous / famous-angular

Bring structure to your Famo.us apps with the power of AngularJS. Famo.us/Angular integrates seamlessly with existing Angular and Famo.us apps.
https://famo.us/angular
Mozilla Public License 2.0
1.92k stars 275 forks source link

scrollview ng-repeat not working with $digest #256

Closed johndoesenior closed 9 years ago

johndoesenior commented 10 years ago

EDIT: To be more specific: When objects are pushed to ng-repeat, all of the fa-views inside except for 1 disappear. when doing a 'touchmove' event on this one surface, the others get rendered again. you can see the behaviour here: https://www.youtube.com/watch?v=ilyrR2k2P64&feature=youtu.be

When refactoring famous-global.js:17910 to:

Scrollview.prototype.getAbsolutePosition = function getAbsolutePosition() {
    if(this._scroller.getCumulativeSize(this.getCurrentIndex())) {
        this._lastSize = this._scroller.getCumulativeSize(this.getCurrentIndex());
    }
    return this._lastSize[this.options.direction] + this.getPosition();
};

No error is triggered, but it takes a touchmove in order to make the surfaces rendered. An updated video attached. https://www.youtube.com/watch?v=j39bqO2h48Y&feature=youtu.be

This is a scrollview with infinite scrolling. very simple: when the scrollview position is near the end of the list it pushes another 5 items. when it does, this error occurs.


BUG:

When trying to add items to a scrollview that has an 'ng-repeat' binded to a <fa-view>, items are not rendered, so to solve it I need to $scope.$digest();

I have uploaded a screencast of the bug: https://www.youtube.com/watch?v=aF3qB2R5QFQ&feature=youtu.be

When doing so, when new items are pushed the scrollview stops to work (you can scroll, but there's a mess and an error is thrown).

Uncaught TypeError: Cannot read property '1' of undefined famous-global.js:17910 (the error triggered by touchmove event).

How to reproduce:

    $scope.items = [];
        function items() { // every 1.5 sec add new item
            setTimeout(function(){
                for(var i =0; i< 5; i++) {
                    $scope.items.push({
                        title: i,
                        color: colors[i]
                    });
                }
                $scope.$digest();
                items();
            }, 1500);

        }

           items(); // init with 5 items
    <fa-scroll-view id="scrollView" fa-options="{direction: 1, margin: 100}" fa-pipe-from="main.eventHandler">
        <fa-view ng-repeat="item in items track by $index">
            <fa-modifier fa-size="[undefined,200]">
                <fa-surface fa-index="$index" class="full-height" fa-background-color="'{{ item.color }}'" fa-pipe-to="main.eventHandler">
                    <div style="color:#fff;">{{ $index }}</div>
                </fa-surface>
            </fa-modifier>
        </fa-view>
    </fa-scroll-view>

Then go to the app, wait for items to be pushed, then just scroll.

johndoesenior commented 10 years ago

CC: @zackbrown

johndoesenior commented 10 years ago

I think that it is mainly caused because i'm using $scope.$digest when pushing the new items, Why are the scrollview events aren't part of the $digest cycle?

The problem occurs when slow-scrolling, when fast scrolling its not happening.

johndoesenior commented 10 years ago

I was able to temporary fix it with setting the position of the scroll after the $apply to its previous location

                            currentLocation = (getScrollView().getAbsolutePosition());
                            $scope.$apply(function(){
                                $scope.todo();
                            });
                            getScrollView().setPosition(currentLocation);
jordanpapaleo commented 9 years ago

Hi -

Can you please fork this codepen and recreate you problem?

Thanks,

Jordan

jordanpapaleo commented 9 years ago

I am going to close this. Please reopen it if it is still an issue. Thanks - Jordan