2017-04-23 100 views
1

无法理解为什么数据不绑定在ui上,尝试使用* ngFor绑定数组,但在数组存在于数组中时不显示任何数据。这里组件代码:数据绑定不工作角2

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); 

    } 
} 

和UI部分:

<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不显示。任何人都知道这里有什么问题?

UPDATE 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

你能告诉我们'youtubeToolsService'更改'on'&'off'方法代码吗? –

+0

@PankajParkar肯定,更新 – Vitaliy

回答

2

基本上要更新视图从外部角上下文结合可变。在这种情况下,zonejs不理解绑定得到更新,并且无法执行更改检测。这就是为什么在这种情况下,您必须运行变更检测功能,循环使用onYoutubeVideosLoaded函数。同样,您可以使用ChangeDetectorRef API &调用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(); 
    //}); 
} 
+0

这是我的解决方案,通过使用ChangeDetectorRef,谢谢! :) – Vitaliy

+1

@Vitaliy太棒了!很高兴帮助你,谢谢:) –