0

I have a list of 'cards' that when a filter is selected on the left side of the screen, the cards shown in the middle of the screen will update accordingly. Here is a snippet of the js:

$scope.isReady = false;

// This is an async method to retrieve from DB          
AssignmentManagerService.getAssignmentsForClass(teacherId, classId).success(function(response) {

    var instances = response.instances;
    $scope.assignmentListData = instances;
    $scope.isReady = true;
});

And here is a piece of the template:

<div flex class="item-list" ng-if="isReady">
    <md-card ng-repeat="assign in assignmentListData track by assign.instanceId"
        ng-click="selectCard(assign)"
        class="item-list-item"
        style="font-size:16px;"
        ng-class="getCardClass(assign)"
        ng-style="getCardStyle(assign)">

        <div>
            <span style='font-weight:500'>Title</span>: {{assign.title}}
        </div>

        <div style="margin-top:10px;">
            <span style='font-weight:500' ng-if="assign.availableDate">Available Date:</span> {{assign.availableDate | date:'fullDate'}}
            <span style='font-weight:500' ng-if="assign.createDate">Create Date:</span> {{assign.createDate | date:'fullDate'}}
        </div>
    </md-card>
</div>

One of two things will happen: I will either get two sections of cards on top of each other, one section with the old selection and one section with the new selection, for a half second before the old selection is removed OR the cards will all be integrated before the old cards are removed. All of this happens within the time span of a second but looks very unprofessional and ugly.

What is supposed to occur is the user makes a filter selection, the cards immediately hide, the new data is retrieved, and the new cards are shown. No overlapping, no multiple groups.

Here's what I have done:

Wrapped the async method/success into a $timeout function: Didn't work. Same results.

Wrapped the async method/success into a $scope.$$postDigest function: Didn't work. Same results.

Added a 400ms thread sleep in the back-end: While it does work, I'm not inserting a back-end fix for a front-end problem.

Tried various combinations of ng-if/ng-show on the div and the md-card: Didn't work. Same results.

The template was originally ~500 lines. I have stripped out all the extraneous markup except for this card bit to see if it was the digest cycle taking too long. Didn't work. Same results.

Any help would be greatly appreciated. Thanks!

dangerisgo
  • 1,261
  • 3
  • 16
  • 28
  • how big is the list? why not retrieve the *entire* list and use a client side `filter` rather than `ng-if`? – Claies Mar 01 '17 at 21:21
  • also, you should not use `.success()`, you should use `.then()`. http://stackoverflow.com/questions/35329384/why-are-angular-http-success-error-methods-deprecated-removed-from-v1-6 – Claies Mar 01 '17 at 21:24
  • With the way the DB is structured, and the filters involved, there's no way to do a client side filter. It has to retrieve items (Searching by class, searching by date range, general search) from the DB every time. As far as how many items? For local/QA, a handful. Production could have hundreds. – dangerisgo Mar 01 '17 at 21:30
  • Are you using the angular $http service or jQuery ajax? – spottexj Mar 01 '17 at 21:37
  • angular $http service – dangerisgo Mar 01 '17 at 21:46
  • I'm not understanding the exact problem. What exactly is slow or doesn't work as it should? And how can adding a thread sleep on the server solve the problem? I don't use material design, but are you sure it doesn't simply add animations that you don't want? – JB Nizet Mar 01 '17 at 22:07
  • When I call $scope.isReady = false; I'm telling it to remove the list of cards so I can modify them and when the new data is retrieved from the server, redisplay the new cards by setting $scope.isReady = true;. What is happening is the old cards are remaining visible on the screen while the new cards are being appended to the list before the old ones are removed. No animations occur. The server thread sleep allows additional time for the cards to be removed for which I shouldn't need to do. – dangerisgo Mar 01 '17 at 22:14
  • There must be some animation going on, because otherwise, the display of the new cards wouldn't happen before the old cards are removed from the DOM by ng-if. Do you have ng-animate in your module dependencies? What happens when you remove it? What are the CSS rules contained in the class item-list? – JB Nizet Mar 01 '17 at 22:35
  • I agree with @JBNizet comment, i'm pretty sure that you have problems with material animations. Try to add this css rule... `.ng-hide.ng-hide-animate{ display: none !important; }`... Check this [post](http://stackoverflow.com/questions/26938021/angular-ng-if-or-ng-show-responds-slow-2second-delay) – The.Bear Mar 02 '17 at 01:16
  • We dont use any specific ngAnimations. I have tried including that css rule along with removing ngAnimate from the app module but it still does the same thing. – dangerisgo Mar 02 '17 at 18:20

1 Answers1

0

Wow. My coworker and I just found some really old and buried CSS animations that were affecting the list in question. After removing them, everything works as it should. Doh! I'd like to thank @The.Bear and @JBNizet for pointing me in the right direction on this!

dangerisgo
  • 1,261
  • 3
  • 16
  • 28