IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Angular Discussion :

Créer un objet dataSource


Sujet :

Angular

  1. #1
    Membre averti
    Homme Profil pro
    Reconversion
    Inscrit en
    Novembre 2018
    Messages
    502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Reconversion
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2018
    Messages : 502
    Points : 300
    Points
    300
    Par défaut Créer un objet dataSource
    Hello,

    Je viens de créer un composant qui récupère un objet 'Customer' d'un formulaire pour l'insérer dans un datagrid (librairie devExtreme) : une ligne est ajoutée à chaque soumission du formulaire et le datagrid actualise la liste des 'customers'.
    Le customer ajouté par dans un fake backend de type json-server.

    En fait le code fonctionne lorsque j'ajoute un customer, je le récupère dans mon pseud backend et une nouvelle ligne avec les données s'ajoute dans le datagrid,
    mais je duplique l'instance de DataSource à chaque souscription pour pouvoir charger le tableau de données (cutomers) dans le dataSource .
    L'idée serait d'implémenter le dataSource beaucoup plus proprement. Je me demandais si un subject ne serait pas utile dans ce cas, mais je maitrise très mal ...le sujet. Merci pour vos suggestions. Je suis preneur d'autres conseils sur les autres défauts sur ce code.

    Voici le model
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    export class Customer {
        id: number;
        firstName: string;
        lastName: string;
        email: string;
        city: string;
        postCode: number;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
     
    ------------------------------------------------------------
    ngOnInit(): void {
        this.initCustomerForm();
        this.getCustomerslist();
      }
     
      initCustomerForm() {
        this.customerForm = this.formBuilder.group({
          firstName: ['', Validators.required],
          lastName: ['', Validators.required],
          email: ['', [Validators.required, Validators.email]],
          city: ['', Validators.required],
          postCode: ['', Validators.pattern("^[0-9]*$")]
        })
      }
     
      onSubmitForm() {
        let customer = new Customer();
     
        customer.firstName = this.customerForm.value['firstName'];
        customer.lastName = this.customerForm.value['lastName'];
        customer.email = this.customerForm.value['email'];
        customer.city = this.customerForm.value['city'];
        customer.postCode = this.customerForm.value['postCode'];
     
        this.dataGridService.addCustomerService(customer).subscribe(() => {
          this.dataSource = new DataSource(
            { store: this.customers }
          );
     
          this.dataSource.store().insert(customer).then(() => this.dataSource.reload());
        });
        this.initCustomerForm();
      }
     
      getCustomerslist() {
        this.dataGridService.getCustomerListService().subscribe(
          list => {
            this.customers = list;
            this.dataSource = new DataSource({
              store: this.customers 
            });
          }
        );
      }
     
      convertIntoPDF() {
        const doc = new jsPDF();
        exportDataGridToPdf({
          jsPDFDocument: doc,
          component: this.dataGrid.instance
        }).then(() => {
          doc.save('customers_list.pdf')
        })
      }
     
    ------------------------------------------------------

  2. #2
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2019
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2019
    Messages : 707
    Points : 1 030
    Points
    1 030
    Par défaut
    (1) deja , pour effacer ton formulaire utilise reset()

    il ne faut pas recréer une instance de form à chaque ligne ajouté !

    (2)
    le behaviorSubject est intéressant !

    d'abord il faut l'initialiser avec une valeur et possible avec null au départ.
    quand on émet sur le behaviorSubject.next(...valeur...);
    - les souscripteurs reçoivent la valeur
    - si il y a des souscripteurs qui souscrivent plus tard, ils reçoivent la dernière valeur (c'est l'avantage du behaviorSubject)

    (3)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    getCustomerslist() {
        this.dataGridService.getCustomerListService().subscribe(
          list => {
            this.customers = list;
            this.dataSource = new DataSource({
              store: this.customers 
            });
          }
        );
      }
    le nommage n'est pas bon :
    getCustomerslist est censé retourner une liste
    hors tu retournes rien du tout
    et en plus dans cette fonction tu initialises DataSource donc tu fais une autre tache

  3. #3
    Membre averti
    Homme Profil pro
    Reconversion
    Inscrit en
    Novembre 2018
    Messages
    502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Reconversion
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2018
    Messages : 502
    Points : 300
    Points
    300
    Par défaut
    Merci Krakatoa,

    Ok pour le 1.

    Pour le 2, est-ce que ça veut dire que je dois récupérer le tableau de données (customers) au niveau du service pour 'initialiser un BehaviorSubject() ?
    un truc du genre :

    Dans le service :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    subjectCustomer = new BehaviorSubject<Customer[]>();
     
    emitCustomers() {
        return this.subjectCustomer.next(customers) // tableau de  customers de l'API
    }
    puis dans le model au niveau du ngOnInit() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      customerSubscription: Subscription;
     
        ngOnInit() {
          this.customerSubscription = this.customerService.subjectCustomer.subscribe(customers => this.customers = customers);
          this.customerService.emitCustomers();
        }

    pour info mon service est très minimaliste, le voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    --------------------------------------------------------------
    getCustomerListService(): Observable<Customer[]> {
        return this.http.get<Customer[]>(`${this.baseUrl}customers`);
      }
     
      addCustomerService(customer: Customer): Observable<Customer> {
       const customerJson  = JSON.stringify(customer);
      return this.http.post<Customer>(`${this.baseUrl}customers`, customerJson, {headers: this.headersOption});
      }
    ----------------------------------------------------------------
    Pour le 3
    ok pour ta 1ere remarque et pour la 2eme effectivement, je pense que l'initialisation du dataSource doit se faire ailleurs, peut-être dans le ngOnInit après avoir récupéré le tableau de données customers, une fois qu'il aura été mis par le subject...ça fait du taf.
    Merci pour tes remarques et tes indications, t'as sauvé mon week end lol. Je reviendrai donner des nouvelles.

  4. #4
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2019
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2019
    Messages : 707
    Points : 1 030
    Points
    1 030
    Par défaut
    je verrais un truc comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    customers: Customer[] = [];
     
    ngOnInit() {
        customerService.subscribe((customers: Customer[]) => {
           this.customers = customers;
           this.initializeDatatable(customers);
       });
       // le form...
    }
     
    addCustomer(customer: Customer) {
      this.customers = {
        ...this.customers,
        customer
      };
     
      this.addToDatatable(customer);
     
      this.form.reset();
     
      // enregistrer en base ?
    }
     
    initializeDatatable(customers: Customer[]) {
      // ajout des customers dans la table
    }
     
    addToDatatable(customer: Customer) {
      // ajoute un customer dans la table
    }

    pour le nommage :

    utilise des mots clés comme : initialize, add (dans une liste), update (quelque chose), remove (dans une liste), delete (quelque chose), get, set, resolve, check, generate...

    initialize c'est quand on ne le fait qu'une fois, au début
    update ou add c'est une répétition

    n'hésite pas à indiquer ou si c'est un cas particulier, vu que tu l'ajoute à un tableau spécifique qui se nomme dataTable alors tu peux mettre : addToDatatable ou addToDatasource... je ne sais pas

    tu peux remarquer que la fonction : addCustomer(customer: Customer) {
    je ne précise pas ou, je suis resté floue parceque je fais plusieurs choses dans cette fonction. je ne me contente pas que de l'ajouter dans une liste.

    peut être aurais-je pu l'appeler : addCustomerAction(customer: Customer) {
    et oui, c'est délicat de trouver le bon nommage.

    si plusieurs, met un S (inutile de mettre list)
    customers, products....

    le nommage des services, exemple :
    api-customer.service.ts (uniquement les requêtes http get, post... concernant Customer)
    customer.service.ts (le code métier, des calculs.... concernant Customer)


    en nommant bien les choses, on comprends vite le code (ainsi pas besoin de mettre du texte explicatif)



    ne pas oublier aussi le typage : Customer, Customer[]

  5. #5
    Membre averti
    Homme Profil pro
    Reconversion
    Inscrit en
    Novembre 2018
    Messages
    502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Reconversion
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2018
    Messages : 502
    Points : 300
    Points
    300
    Par défaut
    Daccord, je vais voir si je pige tout ça ! A voir ce week avec un cerveau à peu près fonctionnel !

  6. #6
    Membre averti
    Homme Profil pro
    Reconversion
    Inscrit en
    Novembre 2018
    Messages
    502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Reconversion
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2018
    Messages : 502
    Points : 300
    Points
    300
    Par défaut
    Du je reviens avec mon compo, y a surement encore des choses à revoir mais j'ai essayé de tenir compte de tes préconisations. En revanche pour l'instant je n'ai pas réussi à utiliser le spread operator, J'ai peu de notions dessus ça sera l'occasion d'éplucher quelques tutos.
    En tout cas quand je le place dans la fonction (addCustomer()) j'ai ceci :
    Nom : operator.png
Affichages : 121
Taille : 127,5 Ko

    Enfin voilà le code...Le but va être de pouvoir faire l'update t le delete maintenant...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
    export class DataGridComponent implements OnInit {
      dataSource: DataSource;
      customers: Customer[];
      customerForm: FormGroup;
     
      @ViewChild(DxDataGridComponent, { static: false }) dataGrid: DxDataGridComponent;
     
      constructor(
        private apiCustomer: ApiCustomerService,
        private formBuilder: FormBuilder) { }
     
      ngOnInit(): void {
        this.apiCustomer.getCustomersService().subscribe((customers: Customer[]) => {
          this.customers = customers;
          this.initializeDatatable(customers);
        });
        this.initCustomerForm();
      }
     
      initializeDatatable(customers: Customer[]): void {
        this.dataSource = new DataSource(
          { store: customers }
        )
      }
     
      initCustomerForm(): void {
        this.customerForm = this.formBuilder.group({
          firstName: ['', Validators.required],
          lastName: ['', Validators.required],
          email: ['', [Validators.required, Validators.email]],
          city: ['', Validators.required],
          postCode: ['', Validators.pattern("^[0-9]*$")]
        })
      }
     
      addCustomer() {
       let customer = {
          firstName:this.customerForm.value['firstName'],
          lastName: this.customerForm.value['lastName'],
          email:  this.customerForm.value['email'],
          city: this.customerForm.value['city'],
          postCode: this.customerForm.value['postCode']
      }
        this.addToDatatable(customer);
        this.customerForm.reset();
      }
     
      addToDatatable(customer: Customer): void {
        this.apiCustomer.addCustomerService(customer).subscribe(() => {
          this.dataSource.store().insert(customer).then(() => this.dataSource.reload());
        });
      }
     
      convertIntoPDF(): void {
        const doc = new jsPDF();
        exportDataGridToPdf({
          jsPDFDocument: doc,
          component: this.dataGrid.instance
        }).then(() => {
          doc.save('customers_list.pdf');
        })
      }
    }
    Si tu peux me donner ton avis..Merci

  7. #7
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2019
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2019
    Messages : 707
    Points : 1 030
    Points
    1 030
    Par défaut
    2 petites modifs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    export class DataGridComponent implements OnInit {
      dataSource: DataSource;
      customers: Customer[];
      customerForm: FormGroup;
     
      @ViewChild(DxDataGridComponent, { static: false }) dataGrid: DxDataGridComponent;
     
      constructor(
        private apiCustomer: ApiCustomerService,
        private formBuilder: FormBuilder) { }
     
      ngOnInit(): void {
        this.apiCustomer.getCustomersService().subscribe((customers: Customer[]) => {
          this.customers = customers;
          this.dataSource =  this.getInitializedDatasource(customers);
        });
         this.customerForm = this.getInitializedCustomerForm();
      }
     
    
      addCustomer() {
       let customer = {
          firstName:this.customerForm.value['firstName'],
          lastName: this.customerForm.value['lastName'],
          email:  this.customerForm.value['email'],
          city: this.customerForm.value['city'],
          postCode: this.customerForm.value['postCode']
      }
        this.addToDatatable(customer);
        this.customerForm.reset();
      }
     
      addToDatatable(customer: Customer): void {
        this.apiCustomer.addCustomerService(customer).subscribe(() => {
          this.dataSource.store().insert(customer).then(() => this.dataSource.reload());
        });
      }
     
      getInitializedDatasource(customers: Customer[]): DataSource{
        return  new DataSource(
          { store: customers }
        )
      }
    
      getInitializedCustomerForm(): FormBuilder {
        return this.formBuilder.group({
          firstName: ['', Validators.required],
          lastName: ['', Validators.required],
          email: ['', [Validators.required, Validators.email]],
          city: ['', Validators.required],
          postCode: ['', Validators.pattern("^[0-9]*$")]
        })
      }
    }

    si tu dois affecter c'est mieux de faire ainsi que d'affecter dans la fonction
    par exemple si tu vois cette fonction : this.dataSource = this.getInitializedDatasource(customers);
    tu comprends que tu mets quelque chose dans : this.dataSource

    par contre : this.initializeDatasource(customers);
    ça saute moins aux yeux.
    parceque on peut initialiser quelque chose sans forcement l'affecter dans une variable

    je le sais que je l'avais pas précisé avant, j'ai oublié.
    pareil avec : this.customerForm = this.getInitializedCustomerForm();


    * sinon mettre le plus possible le code métier dans un service car le contrôleur doit contenir le minimum de code possible :

    customer.service.ts
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
      convertIntoPDF(): void {
        const doc = new jsPDF();
        exportDataGridToPdf({
          jsPDFDocument: doc,
          component: this.dataGrid.instance
        }).then(() => {
          doc.save('customers_list.pdf');
        })
      }

    sinon, dans l'ensemble, cela me parait bien

  8. #8
    Membre averti
    Homme Profil pro
    Reconversion
    Inscrit en
    Novembre 2018
    Messages
    502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Reconversion
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2018
    Messages : 502
    Points : 300
    Points
    300
    Par défaut
    Ok, merc encorei c'est noté, j'ai fait les modifs. C'est vrai qu'il faut morrceler au max le code. Un dernier truc, comme quoi je pige pas encore la philosophie des observables quand je fais ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        console.log("Afficher 'customers' avant souscription " + this.customers)  // retourne undefined
        this.apiCustomer.getCustomersService().subscribe((customers: Customer[]) => {
          this.customers = customers;
          this.dataSource = this.getInitializedDataSource(this.customers);
        });
        console.log("Afficher 'customers' après souscription " + this.customers) // retourne undefined aussi...
    En fait je pensais qu'on récupérait la liste des customers hors du scope de la souscription hors ce n'est pas le cas.
    Du coup comment on fait pour récuperer notre data 'customers' dans le compo si on veut y faire un traitement hors du scope de la souscription ?

  9. #9
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2019
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2019
    Messages : 707
    Points : 1 030
    Points
    1 030
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     console.log("Afficher 'customers' avant souscription " + this.customers)  // retourne undefined
        this.apiCustomer.getCustomersService().subscribe((customers: Customer[]) => {
          this.customers = customers;
          this.dataSource = this.getInitializedDataSource(this.customers);
    //
    //  ici, faire les traitements
        console.log("Afficher 'customers' après souscription " + this.customers) 
    //
        });

    le javascript n'attends pas la reponse de la requete, il poursuit l'execution du code
    et donc s'il lui faut 30ms pour recuperer le resultat, c'est trop tard i la continuer et avec le console.log et est donc undefined

  10. #10
    Membre averti
    Homme Profil pro
    Reconversion
    Inscrit en
    Novembre 2018
    Messages
    502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Reconversion
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2018
    Messages : 502
    Points : 300
    Points
    300
    Par défaut
    oui ok, le get est de toute façon asynchrone effectivement, doncc'est logique...Merci pour toute ton aide.Oserai-je dire à bientôt ?

  11. #11
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2019
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2019
    Messages : 707
    Points : 1 030
    Points
    1 030
    Par défaut
    oui osons, soyons fou

    à bientôt l'ami

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Travailler / Créer des objets complexes
    Par Ekinoks dans le forum OpenGL
    Réponses: 3
    Dernier message: 22/08/2005, 14h38
  2. [C#] Créer des objets Winform personnalisés
    Par KibitO dans le forum Windows Forms
    Réponses: 8
    Dernier message: 31/05/2005, 17h09
  3. [Info]Créer un objet persistent
    Par seb55555 dans le forum JDBC
    Réponses: 5
    Dernier message: 22/02/2005, 16h53
  4. [VBA ActivX] Créer un objet Name [OWC10.Spreadsheet.10]
    Par FRED.G dans le forum VBA Access
    Réponses: 12
    Dernier message: 06/07/2004, 16h29
  5. Créer des objets sur la pile ?
    Par Cornell dans le forum Langage
    Réponses: 8
    Dernier message: 03/03/2003, 11h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo