数据绑定不工作角2

时间:2017-04-23 16:32:06

标签: angular typescript angular2-routing

无法理解为什么数据没有绑定到ui,尝试使用* ngFor绑定数组,但是当数据存在于数组中时,ui上没有显示任何内容。这里是组件代码:

import { Component, Injector, OnInit, OnDestroy, Pipe } from '@angular/core'
import { AdvancedPostsService } from '../../services/advanced.posts.service'
import { SpinnerService } from '../../services/spinner.service'
import { PathKey } from '../../helpers/platform.helpers'
import { Router } from '@angular/router'
import { ToolsService } from '../../services/tools.service'
import { YoutubeToolsService } from '../../services/youtube.tools.service'

@Pipe({ name: 'safe' })
@Component({
    selector: 'advanced-post-youtube-step-component',
    templateUrl: '../../templates/advanced-posts-templates/advanced.post.youtube.component.html'
})
export class AdvancedPostYoutubeStep implements OnInit, OnDestroy {

    private postId: number;
    private stepId: number;
    private postType: number;
    videoList: any[] = [];
    private youTubeWatchUrl = "https://www.youtube.com/embed/";
    i = 0;

    constructor(private advancedPostsService: AdvancedPostsService,
        private spinner: SpinnerService,
        private toolsService: ToolsService,
        private injector: Injector,
        private router: Router,
        private youtubeToolsService: YoutubeToolsService) {
        this.injectParentData();
    }

    ngOnInit(): void {
        this.youtubeToolsService.change.on(this.onYoutubeVideosLoaded.bind(this));
        this.youtubeToolsService.initGoogleAuthentication();
        this.spinner.stop();
    }

    onYoutubeVideosLoaded(self: YoutubeToolsService) {
        for (let item of self.videoList) {
            if (item) {
                console.log(item);
                this.videoList.push({
                    id: item.snippet.resourceId.videoId,
                    url: this.youTubeWatchUrl + item.snippet.resourceId.videoId
                });
            }
        }
        console.log(this.videoList);
    }

    ngOnDestroy(): void {
        this.youtubeToolsService.change.off(this.onYoutubeVideosLoaded.bind(this));
        this.spinner.start();
    }

    injectParentData() {
        this.postId = this.injector.get(PathKey.PostId);
        this.stepId = this.injector.get(PathKey.StepId);
        this.postType = this.injector.get(PathKey.PostType);

    }
}

而且你的部分:

<div class="col-md-6 col-md-offset-3">
    <h3 class="text-center">Select video</h3>

    <div>
        <iframe *ngFor="let video of videoList" type="text/html" class="video-responsive" [src]="video?.url | safe" frameborder="0"></iframe>
    </div>
    <h4>{{videoList.length}}</h4>
</div>

甚至videoList.lenth都没有显示。有人知道这里有什么问题吗?

更新 YoutubeToolsService代码:

import { NgZone, Injectable} from '@angular/core'
import { OperationDataResult } from '../helpers/operation.models'
import { Config } from '../helpers/social.models'
import { LiteEvent } from '../helpers/lite.event'
import { SocialService } from '../services/social.service'


declare var gapi: any;

@Injectable()
export class YoutubeToolsService {

    private loginStatus: any;
    private onChange = new LiteEvent<YoutubeToolsService>();
    get change() { return this.onChange.expose(); }
    videoList: any[] = [];

    requestVideoPlaylist(playlistId) {
        var requestOptions = {
            playlistId: playlistId,
            part: 'snippet',
            maxResults: 10
        };

        var request = gapi.client.youtube.playlistItems.list(requestOptions);
        request.execute(response => {
            var playlistItems = response.result.items;
            if (playlistItems) {

                this.videoList = playlistItems;
                this.onChange.trigger(this);
            }
        });
    }

1 个答案:

答案 0 :(得分:2)

基本上,您正在从Angular上下文更新视图绑定变量。在那种情况下,zonejs不了解绑定得到更新并且无法执行更改检测。这就是为什么在这种情况下,您可以在onYoutubeVideosLoaded函数内运行变更检测循环。对于同样的原因,您可以使用ChangeDetectorRef API&amp;每当您想要运行更改检测以手动更新绑定时,请调用detectChanges方法。

constructor(private ref: ChangeDetectorRef) { }; //inject & import ChangeDetectorRef
//OR
//constructor(private _ngZone: NgZone) { }; //make sure constructor have NgZone

onYoutubeVideosLoaded(self: YoutubeToolsService) {
    //below commented that can be alternative way of doing it
    //this._ngZone.run(() => {
      for (let item of self.videoList) {
        if (item) {
            console.log(item);
            this.videoList.push({
                id: item.snippet.resourceId.videoId,
                url: this.youTubeWatchUrl + item.snippet.resourceId.videoId
            });
        }
      }
      //running CD manually
      this.ref.detectChanges();
    //});
}