简体   繁体   中英

Angular - *ngFor: Passing i from index in ts file

I'm trying to pass the index from a ngFor to a my ts file without any success. I actually don't know how to do that. Can someone tell me how to pass the index value from the html to the ts file? I thought using a @Input would be te solution but nothing happen... Thanks.

My HTML:

<div *ngFor="let question of questions | async; index as i">{{question.libelle}}
     <div class="row text-left options">
        <div class="col-md-6" *ngFor="let reponse of reponses | async">
          <div class="option">
            <label class="" [attr.for]="reponse.id">
                <input type="checkbox" [(ngModel)]="reponse.Selected"/>
                {{reponse.libelle}}
            </label>
          </div>
        </div>
      </div>
      {{i}}
    </div>

My TS:

@Injectable()


@Component({
  selector: 'app-java',
  templateUrl: './java.component.html',
  styleUrls: ['./java.component.sass']
})
export class JavaComponent implements OnInit {
  @Input()  i : any;
  questions :any = [];
  reponses :any = [];
  constructor(private questionnaireService: QuestionnaireService) { }

  ngOnInit() {
    this.questions = this.questionnaireService.getQuestion();
    this.reponses = this.questionnaireService.getReponse(this.i);
  }  

}

you seem to have a basic misunderstanding of the index variable context and how observables will work. What could help here and clear things up is dividing your component into two components, one for managing and displaying the overall list and one for managing and displaying the child lists

The parent (app-java):

HTML:

<div *ngFor="let question of questions | async; index as i">{{question.libelle}}
 <div class="row text-left options">
    <app-java-child [i]="i"></app-java-child>
  </div>
  {{i}}
</div>

TS:

@Component({
  selector: 'app-java',
  templateUrl: './java.component.html',
  styleUrls: ['./java.component.sass']
})
export class JavaComponent implements OnInit {
  questions :any = [];
  constructor(private questionnaireService: QuestionnaireService) { }

  ngOnInit() {
    this.questions = this.questionnaireService.getQuestion();
  }  

}

and the child:

HTML:

<div class="col-md-6" *ngFor="let reponse of reponses | async">
   <div class="option">
     <label class="" [attr.for]="reponse.id">
            <input type="checkbox" [(ngModel)]="reponse.Selected"/>
            {{reponse.libelle}}
     </label>
   </div>
</div>

TS:

@Component({
  selector: 'app-java-child',
  templateUrl: './java-child.component.html',
  styleUrls: ['./java-child.component.sass']
})
export class JavaChildComponent implements OnInit {
  @Input()  i : any;
  reponses :any = [];
  constructor(private questionnaireService: QuestionnaireService) { }

  ngOnInit() {
    this.reponses = this.questionnaireService.getReponse(this.i);
  }  

}

This way you take the index from the initial ngFor and feed it to the child as input so the children can be in charge of building their own response arrays.

You can achieve these with 3 steps

  1. Keep the currentIndex in ts file

  2. Set the currentIndex from the html

  3. Call getter method from the *ngFor

in ts

@Injectable()
@Component({
  selector: 'app-java',
  templateUrl: './java.component.html',
  styleUrls: ['./java.component.sass']
})
export class JavaComponent implements OnInit {
  @Input()  i : any;
  questions :any = [];
  reponses :any = [];
  constructor(private questionnaireService: QuestionnaireService) { }

  ngOnInit() {
    this.questions = this.questionnaireService.getQuestion();
  }  

   //Track the current Index
   public currentIndex;

   //Current Index Setter
   setCurrentIndex(index){
       this.currentIndex = index;
   }

  //Getter for response which will use currentIndex
  get responses(){
    return this.questionnaireService.getReponses(this.currentIndex)
  }

}

in html

   <div *ngFor="let question of questions | async; index as i">{{question.libelle}}
         <div class="row text-left options" #>

            {{setCurrentIndex(i)}} <-- Set the current Index -->

            <div class="col-md-6" *ngFor="let reponse of responses | async">
              <div class="option">
                <label class="" [attr.for]="reponse.id">
                    <input type="checkbox" [(ngModel)]="reponse.Selected"/>
                    {{reponse.libelle}}
                </label>
              </div>
            </div>
          </div>
          {{i}}
 </div>

Note : since you are using async pipe make sure all your results are Observable.

normally <div *ngFor="... let ii==index"> will be enough to pass the ii, however, in my case there is a *ngIf in sub, so that messed up the count and made it undefined. I endup make the *ngIf on the top level above *ngFor.

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