关于Sort Tab Object (ANGULAR,TS)显示“冠军分类”的问题

Issue about Sort Tab Object (ANGULAR,TS) to display " championship classification "

Joueur-Firebase

import { Component, OnInit, Output ,HostBinding, OnDestroy} from '@angular/core';
import { Router } from '@angular/router';
import { Joueur } from '../models/joueur.model';
import { Match } from '../models/match.model';
import { JoueurService } from '../services/joueur.service';
import { Subscription } from 'rxjs';
import * as firebase from 'Firebase';




@Component({
  selector: 'app-classement',
  templateUrl: './classement.component.html',
  styleUrls: ['./classement.component.scss']
})
export class ClassementComponent implements OnInit, OnDestroy 
{  
  matchClassement: Match[]
  joueurClassement: Joueur[]
  @Output() PouleClassement: any;
  classementSubscription: Subscription;
  matchSubscription: Subscription;
  match: Match;
  constructor(private joueurService: JoueurService, private router: Router) { }

  ngOnInit() {
    this.classementSubscription = this.joueurService.classementSubject.subscribe(
      (joueurClassement: Joueur[]) => {
        this.joueurClassement = joueurClassement;
      }      
    );
    this.PouleClassement = this.joueurService.getPoule();
    this.joueurService.getPouleClassement(this.PouleClassement);
   this.joueurService.emitJoueurClassement();  
   // tri du tableau 
   
   console.table(this.joueurClassement)

   const sortByMapped = (map,compareFn) => (a,b) => compareFn(map(a),map(b));
   const byValue = (a,b) => b - a;
   const toPoint = e => e.point;
   const byPoint = sortByMapped(toPoint,byValue);
   this.joueurClassement.sort(byPoint)

    this.matchSubscription = this.joueurService.matchSubject.subscribe(
     (matchClassement: Match[]) => {
       this.matchClassement = matchClassement;
      }      
  ); 
  this.joueurService.getMatch(this.PouleClassement);
  this.joueurService.emitMatch(); 
  
}
 
  onBack() {
    this.router.navigate(['/poules']);
  }

  onCreatMatch(poule: any) {
     //var P = 1; 
     var TabIndexe = new Array
     
     var NumMatch = 0;
     this.match = new Match(0,'','',0,'','',0);
   
     // fabrication du tableau d'indexe
     var i = 0;
     for ( let J1 in this.joueurClassement ){
          TabIndexe[i] = J1;
          i ++;
     }
     console.table(TabIndexe)
    // creation des matchs
     var P1 = 0;
     var P2 = 1 ;
     console.table(this.joueurClassement)
     while ( P1 < TabIndexe.length ){
       while (P2< TabIndexe.length ){
        var ind = TabIndexe[P1] 
        var ind1 = TabIndexe[(P2)]
        this.match.numMatch = NumMatch
        this.match.joueur1 = this.joueurClassement[ind].nom;
        this.match.prenom1 = this.joueurClassement[ind].prenom;
        this.match.joueur2 = this.joueurClassement[ind1].nom;
        this.match.prenom2 = this.joueurClassement[ind1].prenom;
        this.match.point1 = 0;
        this.match.point2 = 0;
        console.log(  this.match.numMatch + this.match.joueur1 + this.match.joueur2 )
        firebase.database().ref('/poule' + poule + '/' + NumMatch ).set(this.match);
        P2++ 
        NumMatch++
     }
      P1++ 
      P2  = P1 + 1
  }
  }



  ngOnDestroy(){
   this.classementSubscription.unsubscribe();
 }
 
 onSaveMatch(poule,numMatch,joueur1,joueur2){
   this.joueurService.setPoule(poule);
   this.joueurService.setMatch(numMatch,joueur1,joueur2)
  this.router.navigate(['/classement/match']);
 }
 
 trackKeyValuePair(_index, keyValuePair): number {
  return keyValuePair.key;
}



}

import { Injectable } from '@angular/core';
import  {Joueur} from '../models/joueur.model';
import  {Match} from '../models/match.model';
import { Subject } from 'rxjs';
import * as firebase from 'Firebase';


@Injectable({
  providedIn: 'root'
})
export class JoueurService {
  
  match: Match[] = [];
  joueur: Joueur[] = [];
  joueurClassement: Joueur[] = [];
  joueurSubject = new Subject<Joueur[]>();
  matchSubject = new Subject<Match[]>();
  classementSubject = new Subject<Joueur[]>();

  constructor() { }
  emitJoueur() {
    this.joueurSubject.next(this.joueur);
  }

  emitJoueurClassement() {
   this.classementSubject.next(this.joueurClassement);
  }
  emitMatch() {
    this.matchSubject.next(this.match);
  }
  saveJoueur(){
    firebase.database().ref('/joueurs').set(this.joueur); 
  }

 
  getJoueur(){
    firebase.database().ref('/joueurs').on('value', (data) => {
      this.joueur = data.val() ? data.val() : [] ;
      this.emitJoueur();
    });
  }

  getSingleJoueur(id: number){
      return new Promise(
         (resolve, reject) => {
          firebase.database().ref( '/joueurs/' + id).once('value').then(
            (data) =>{
              resolve(data.val());
            }
            ,(error) =>{
              reject(error);
            }
          );
        }
      );
    }
 creatNewJoueur(newJoueur: Joueur , poule){
      this.joueur.push(newJoueur);
      this.saveJoueur();
      this.emitJoueur();
    }


  removeJoueur(joueur: Joueur){
      const JoueurIndexToRemove = this.joueur.findIndex(
        (joueurEl) => {
          if(joueurEl === joueur){
            return true;
          }
        }
      );
      this.joueur.splice(JoueurIndexToRemove,1);
      this.saveJoueur();
      this.emitJoueur();
  }
   
  getPouleClassement(poule: any){
    console.log("Service = getPouleClassement" + poule );
    firebase.database().ref('/joueurs').orderByChild('poule')
                                       .equalTo(poule)
                                       .on("value",  (data) => {                                     
                                        this.joueurClassement= (data.val() ? data.val() : []);
                                                                        
                                        this.emitJoueurClassement();                                                                      
                                      });
                                       
   
} 
// sauvegarde et transmission 
  Poule: any;
  setPoule(poule){
      this.Poule =poule;
  } 
//et transmission du numero de poule
  getPoule(){
    let PouleClassement = this.Poule;
      this.clearData();
    return PouleClassement;
    }

  // sauvegarde et transmission 
  nummatch: any;
  joueur1: any;
  joueur2: any;

  setMatch(nummatch,joueur1,joueur2){
      this.nummatch =nummatch;
      this.joueur1 =joueur1;
      this.joueur2 =joueur2;

  } 
//et transmission 
  getNumMatch(){
   let NumMatch = this.nummatch;   
      this.clearData1()
    return NumMatch;
    }  

    getJoueur1(){
     let Joueur1 = this.joueur1;  
         this.clearData2();
       return Joueur1;       
       }  

   getJoueur2(){
    let Joueur2 = this.joueur2;  
        this.clearData3();
      return Joueur2;       
    }  

    clearData(){
      this.Poule = undefined;
    }

    clearData1(){
      this.nummatch = undefined;
    }

    clearData2(){
      this.joueur1 = undefined;
    }
  
  clearData3(){
    this.joueur2 = undefined;
  }
    
    
   
  getMatch(poule)  {
    firebase.database().ref('poule'+ poule).on('value', (data) => {
      this.match = data.val() ? data.val() : [] ;
      this.emitMatch();
  }
  )
}
updateMatch(poule,numMatch,score1,score2){
  firebase.database().ref('poule'+ poule +  '/' + numMatch ).update({point1:score1 , point2:score2 })
  
}

updateJoueur(indexe,point,victoire,defaite,nbdejeu){
  firebase.database().ref('joueurs/'+ indexe  ).update({point:point , victoire:victoire ,defaite:defaite ,nbdejeu: nbdejeu  })
}


}

我想按 Point 对网球运动员进行排序。下面是我的 Scream (HTLM + Ts) 的图片 Sort OK

下面是 CODE Typescript:我的对象选项卡是 joueurClassement,所以我在 HTLM joueurClassement 中显示

const sortByMapped = (map,compareFn) => (a,b) => compareFn(map(a),map(b));
   const byValue = (a,b) => a - b;
   const toPoint = e => e.point;
   const byPoint = sortByMapped(toPoint,byValue);
   this.joueurClassement.sort(byPoint)

但有时 "sort function" 是 KO 。这是这个问题的图片: sort KO 错误类型错误: this.joueurClassement.sort 不是函数

不知道为什么有时候是Ok或者KO。可能是indexTab不好? 你能帮帮我吗?

是否可以共享您的组件代码以查看您的 table 在哪里构建/初始化,因为通常此错误应该意味着您对象 joueuerClassement 不是数组,因此它没有排序功能。

Firebase 存储数组的方式有点奇怪,我认为您应该将玩家存储为集合而不是数组。当您将数组发送到 firebase 数据库时,它会将其存储为这样的对象:

// send this array
[{name: 'foo', age: 25}, {name: 'bar', age: 30}]

// Stored like this
{
  "0": {name: "foo", age: 25},
  "1": {name: "bar", age: 30}
}

因此,从技术上讲,当您获取数据时,firebase 数据库将 return 一个对象,但在某些条件下它应该被转换为数组。详情请看这篇文章

https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html

我认为最好为 "joueurs" 使用一个集合,并为集合中的每个 joueur 设置一个唯一的 ID。

抱歉,我没有看到您的 Firebase 集合的屏幕截图。好吧,所以如果你想把你的 joueurs 集合保存为一个数组,你可以在你从你的服务中得到结果时检查你的对象是否是一个数组,如果不是,就把它转换成这样的数组

let joueurs = data.val();
if (joueurs) {
  if (Array.isArray(joueurs) {
    // joueurs is an array // no conversion needed
  } else {
    // Assume that joueurs is an object
    let joueursTable = [];
    // for each "indexed" property "0", "1", etc... add its value to joueursTable
    Object.keys(joueurs)
    .filter(key => Number.isInteger(Number(key)))
    .forEach(key => joueursTable[key] = joueurs[key]);
    console.log(joueursTable) // --> Here should have your object converted to array
  }
} else {
  // empty result 
}

希望对你有帮助。