简体   繁体   中英

Angular 2 HTTP response animations

I'd like to run jQuery animations after a HTTP response has been received by the client.

My web service, it's a simple web service that uses AngularJS's Http functionality:

import {Component, View, Injectable} from 'angular2/core';
import {Http, HTTP_PROVIDERS} from 'angular2/http';
import {JsonObj} from './JsonObj.class';
@Injectable()
export class WebService {
    private http: Http;

constructor(http: Http) {
    this.http = http;
}

get(url: string) {
    return this.http.get(url)
        // Call map on the response observable to get the parsed people object
        .map(res => {
            let _d = res.json();
            return new JsonObj(_d.code, _d.status, _d.data, _d.error);
        });
    }
}

The JsonObj, this is simply an object that hosts the data from the web service:

export class JsonObj {
private code: Number;
private status: String;
private data: any;
private error: Array<any>;

constructor(_c: Number, _s: String, _d: Array<any>, _e: Array<any>) {
    this.code = _c;
    this.status = _s;
    this.data = _d;
    this.error = _e;
}

getCode() {
    return this.code;
}
getStatus() {
    return this.status;
}
getData() {
    return this.data;
}
getError() {
    return this.error;
}
}

The Component making the web service call:

import {Component, ElementRef} from 'angular2/core';
import {Http, HTTP_PROVIDERS} from 'angular2/http';
import {Rotate} from './Rotate.class';
import {WebService} from '../../App/js/WebService.class';

@Component({
selector: 'Reviews',
viewProviders: [HTTP_PROVIDERS],
templateUrl: 'assets/templates/reviews.template.html'
})
export class Reviews {
public review: Array<any>;
private speed = 5000;
private outElem = null;
private parentElem = null;
private interval = null;

constructor(ws: WebService, el: ElementRef) {
    console.log('Reviews');

    ws.get('assets/temp_quotes.json').subscribe(
        data => this.review = data.getData().reviews,
        err => console.log('Error getting Review feed', err.getCode(), err.getError()),
        () => {
            console.log('Successful retrieval of the Review feed', this.review);
            let rotator = new Rotate(el);
            rotator.loop();
        }
    );
}
}

The template, the ngFor loops through the data from the web service and outputs it:

<div class="feedback-wrapper">
    <div class="quote_overlay hide" style="display: none;"></div>
    <h4>What people have to say about us...</h4>
    <ul>
        <li *ngFor="#el of review" class="hide" style="display: none;">
            <p class="quote">{{el.quote}}</p>
            <p class="author">{{el.name}}, United Kingdom<br>Reviews.co.uk, {{el.date}}</p>
        </li>
    </ul>
    <p class="show-right"><a href="/testimonials.htm">Read all Reviews</a></p>
</div>

My problem is that when the Component calls this:

let rotator = new Rotate(el);
rotator.loop();

the el (ElementRef) content from the web service has not been populated even though the dom has been updated with the response. It seems that rotator.loop() has been called too soon. I want to do an animation that loops through each of the list items one at a time. Any idea on how that can be done correctly?

Whatever comes last starts the animation

constructor(ws: WebService, el: ElementRef) {
  console.log('Reviews');
  private _initialized: boolean false;

  ws.get('assets/temp_quotes.json').subscribe(
    data => this.review = data.getData().reviews,
    err => console.log('Error getting Review feed', err.getCode(), err.getError()),
    () => {
        console.log('Successful retrieval of the Review feed', this.review);
        if(!this._initialized) {
          this._initialized = true; 
        } else {
          this.startAnimation();
        }
    });
  }

  ngAfterViewInit() {
    if(!this._initialized) {
      this._initialized = true;
    } else {
      this.startAnimation();
    }
  }
  startAnimation() {
    let rotator = new Rotate(el);
    rotator.loop();
  }
}

You could also create an observable and add an event when getData() completed and another one in ngAfterViewInit() . Subscribe on the observable, ignore the first event and execute startAnimation() on the 2nd and than cancel the subscription. I don't use TS myself therefore it's hard for me to provide a code example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM