简体   繁体   English

angular4 更改检测更新 ngfor 中的所有组件

[英]angular4 change detection update all components inside ngfor

I have 2 components:我有两个组件:

  • x-list-component and xcomponent. x-list-component 和 xcomponent。

  • x-list-component uses the *ngfor='let VAR of array' directive to create a list of xcomponent and pasts VAR as an input to xcomponent. x-list-component 使用 *ngfor='let VAR of array' 指令创建一个 xcomponent 列表,并将 VAR 作为 xcomponent 的输入。

     <xcomponent [VAR]='VAR'></xcomponent>

xcomponent uses interpolation in the template to render the passed VAR inside a div. xcomponent 在模板中使用插值在 div 内呈现传递的 VAR。 {{VAR.args}} {{VAR.args}}

Everything is ok but when changedetection occurs inside one instance of xcomponent the view is rerendered and the new value of VAR.args appears by all the others xcomponents instead of only on the xcomponent which modified his VAR.args.一切正常,但是当更改检测发生在 xcomponent 的一个实例中时,视图会重新呈现,并且所有其他 xcomponents 会出现 VAR.args 的新值,而不是仅在修改其 VAR.args 的 xcomponent 上出现。

so I want to know how I can only updates the view of the xcomponent which emitted the change detection and keep the state of others xcomponents unchanged.所以我想知道我如何只能更新发出更改检测的 xcomponent 的视图并保持其他 xcomponents 的状态不变。

//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>

It is because on your ngOnInit you are getting the element by id from the hard-coded value "test" .这是因为在您的ngOnInit您是通过 id 从硬编码值"test"获取元素。 Then for all your kamerokeComponent components there will be only one widget element.那么对于您的所有kamerokeComponent组件,将只有一个小部件元素。 So when you change that all of your kamerokeComponent values will get changed.因此,当您更改所有kamerokeComponent值时,都会更改。 I suggest to pass the id of the element as well.我建议也传递元素的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;   
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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