angular4 change detection更新ngfor中的所有组件

时间:2018-05-17 00:39:48

标签: angular ngfor

首先我为我的英语道歉。我有两个组成部分:  x-list-component和xcomponent。  x-list-component使用* ngfor =' let VAR of array'指令,用于创建xcomponent和pasts VAR列表作为xcomponent的输入。          xcomponent在模板中使用插值来渲染div中传递的VAR。         {{VAR.args}}  一切都还可以但是当在xcomponent的一个实例中发生changedetection时,视图会被重新渲染,并且所有其他xcomponents都会出现VAR.args的新值,而不是仅在修改了他的VAR.args的xcomponent上。 所以我想知道我怎么只能更新发出变化检测的xcomponent的视图,并保持其他xcomponents的状态不变。 THKS

//list component and his template
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-kameroke-list',
  templateUrl: './kameroke-list.component.html',
  styleUrls: ['./kameroke-list.component.css']
})
export class KamerokeListComponent implements OnInit {
  lyrics=[{"first":"paroles","second":"paroles2","third":"paroles3","id":"test"},
  {"first":"lyrics","second":"lyrics2","third":"lyrics3","id":"secondTest"}
  ];
  constructor() { }

  ngOnInit() {
  }

}


<!--template for list-component-->
    <app-kameroke *ngFor="let lyric of lyrics"  [first]="lyric.first" [second]="lyric.second" [third]="lyric.third"></app-kameroke>

<!--attribuer un id dynamiquement : [attr.id]="lyric.id"-->





//kamerokeComponent and his template
import { Component, OnInit , Input ,ChangeDetectorRef } from '@angular/core';

@Component({
  selector: 'app-kameroke',
  templateUrl: './kameroke.component.html',
  styleUrls: ['./kameroke.component.css']
})
export class KamerokeComponent implements OnInit {
  @Input() url:string;
  @Input() private first:string;
  @Input() private second:string;
  @Input() private third:string;
  masked:boolean=true;
  playing:boolean=false;

  widget :any;
  lyrics:object;

  constructor(private ref:ChangeDetectorRef) {
  }

  ngOnInit() {
    //all this event in insertFrame
    this.lyrics={
      1:"ca marche",
      2:"ca cartonne",
      3:"c le feu",
      4:"testons voir"
    };
    this.widget=window['SC'].Widget(document.getElementById("test"));
    this.widget.bind(window['SC'].Widget.Events.PLAY,()=>{this.playing=true});
    this.widget.bind(window['SC'].Widget.Events.PAUSE,()=>{this.playing=false});
    this.widget.bind(window['SC'].Widget.Events.FINISH,()=>{this.playing=false});
    this.widget.bind(window['SC'].Widget.Events.PLAY_PROGRESS,()=>{
     this.widget.getPosition(
                (time)=>{
          //TODO set les variables first second and third
          if(this.lyrics){
            let timing=Math.ceil(time/1000);
            //console.log(this.lyrics[timing]);
            if(this.lyrics[timing]){
              console.log(timing);
              this.first=this.lyrics[timing];
              this.second=this.lyrics[timing];
              this.third=this.lyrics[timing];
              this.ref.detectChanges();
              }
            }
          }
                );
    });


  }
  hide(){
    this.masked=false;   
  }
}

<!--kamerokeComponent template-->
<div class="container">
  <div class="row">
    <div class="col-sm soundcloudCol">
        <iframe (load)="hide()" id="test" allow="autoplay" width="100%" height="100%" scrolling="no" frameborder="no"
        src="https://w.soundcloud.com/player/?url=https://soundcloud.com/maahlox/la-vie-cest-la-bastonde&amp;{ ADD YOUR PARAMETERS HERE }">
        </iframe>
    </div>
  </div>
  <div  class="row lyrics" [hidden]="masked" >
    <div class="col-sm">
        <br><br>
        <p class="first">{{first}}</p>
        <p class="second">{{second}}</p>
        <p class="second">{{third}}</p>
    </div>
  </div>
</div>

1 个答案:

答案 0 :(得分:0)

这是因为在您的ngOnInit上,您从硬编码值"test"获取了id的元素。然后,对于您的所有kamerokeComponent组件,将只有一个小部件元素。因此,当您更改时,所有kamerokeComponent值都会发生变化。我建议也传递元素的id

// template for list-component
<app-kameroke *ngFor="let lyric of lyrics"  [first]="lyric.first"
  [second]="lyric.second" [third]="lyric.third" [id]="lyric.id"></app-kameroke>
//kamerokeComponent
import { Component, OnInit , Input ,ChangeDetectorRef } from '@angular/core';

@Component({
   selector: 'app-kameroke',
   templateUrl: './kameroke.component.html',
   styleUrls: ['./kameroke.component.css']
})
export class KamerokeComponent {
   @Input() url:string;
   @Input() private first:string;
   @Input() private second:string;
   @Input() private third:string;
   @Input() private id:string;
   masked:boolean=true;
   playing:boolean=false;

   widget :any;
   lyrics:object;

   constructor(private ref:ChangeDetectorRef) {
   }

   ngAfterViewInit() {
      //all this event in insertFrame
      this.lyrics={
         1:"ca marche",
         2:"ca cartonne",
         3:"c le feu",
         4:"testons voir"
      };
      this.widget=window['SC'].Widget(document.getElementById(this.id));
      this.widget.bind(window['SC'].Widget.Events.PLAY,()=>{this.playing=true});
      this.widget.bind(window['SC'].Widget.Events.PAUSE,()=>{this.playing=false});
      this.widget.bind(window['SC'].Widget.Events.FINISH,()=>{this.playing=false});
      this.widget.bind(window['SC'].Widget.Events.PLAY_PROGRESS,()=>{
      this.widget.getPosition((time)=>{
         //TODO set les variables first second and third
         if(this.lyrics){
            let timing=Math.ceil(time/1000);
            //console.log(this.lyrics[timing]);
            if(this.lyrics[timing]){
              console.log(timing);
              this.first=this.lyrics[timing];
              this.second=this.lyrics[timing];
              this.third=this.lyrics[timing];
              this.ref.detectChanges();
           }
        }
      });
   });
  }
   hide(){
      this.masked=false;   
   }
}