0

J'ai un problème avec la liaison de données bidirectionnelle AngularJS. Je vais essayer d'expliquer le problème aussi clairement que possible: j'ai une liste de noms de contacts. Pour chaque élément, j'ai un bouton Modifier. Lorsque je clique sur ce bouton, je charge le contact complet "cliqué" à partir d'un appel Ajax et ensuite je montre une fenêtre avec des champs de saisie liés au contact que je viens de récupérer ("téléphone", "email" etc.). Ceci est la pièce intéressante de la vue:Liaison de données bidirectionnelle après un appel Ajax

<div>  
    <div class="contact" data-ng-repeat="contact in contacts"> 
     <span>{{contact.label}}</span> 
     <a href="" class="btn btn-xs btn-default" data-ng-click="openContactModal(contact.ID)"> 
      Edit 
     </a> 
    </div> 
</div> 

Le clic sur le bouton Modifier les feux de cette fonction (présent dans le contrôleur):

var newContact = null; 
$scope.openContactModal = function(contactID){ 
    newContact = new Contact(contactID); 
    newContact.onLoad().then(
     function(){ 
      //loading OK 
      $('#myModal').modal('show'); 
     }, 
     function(){ 
      //loading Error 

     } 
    ); 
    $scope.newContact = newContact; 
}; 

L'appel à new Contact(contactID) charge un contact de la base de données avec un appel Ajax. J'ouvre la fenêtre modale à la fin de l'appel Ajax (en attendant la promesse AngularJS). Dans le modal, cependant, tous les champs sont vides même s'ils sont liés au modèle de contact (newContact.phone, newContact.email etc.). J'ai déjà vérifié que l'appel Ajax fonctionne bien (impression du résultat JSON). Je suppose qu'il me manque quelque chose dans le problème de liaison de données bidirectionnelle. Le fait étrange est que, si j'essaie de remplir les champs modaux vides, le modèle newContact réagit bien, comme si la liaison de données bidirectionnelle fonctionne bien de la vue au modèle, mais pas l'inverse. Merci d'avance!

EDIT: c'est le service qui récupère le contact:

angular.module("app").factory("Contact", ["ContactDBServices", "$q", 
    function(ContactDBServices, $q){ 
     return function(contactID){ 

      //the contact itself 
      var self = this; 

      var contactPromise = $q.defer(); 

      //attributi del contatto 
      this.firstName = null; 
      this.ID = null; 
      this.lastName = null; 
      this.phone = null; 
      this.fax = null; 
      this.mobile = null; 
      this.email = null; 
      this.web = null; 

      //the Ajax call  
      var metacontact = ContactDBServices.find({ID:contactID}, 
       function(){ 
        this.ID = contactID; 
        this.firstName = metacontact.contact_name; 
        this.lastName = metacontact.contact_last_name; 
        this.phone = metacontact.contact_phone; 
        this.fax = metacontact.contact_fax; 
        this.mobile = metacontact.contact_mobile; 
        this.email = metacontact.contact_email; 
        this.web = metacontact.contact_web; 

        //!!!THE FOLLOWING PRINTS ARE GOOD!!!! 
        console.log(this.ID); 
        console.log(this.firstName); 
        console.log(this.lastName); 
        console.log(this.phone); 
        console.log(this.fax); 
        contactPromise.resolve("OK"); 
       }, 
       function(){ 
        contactPromise.reject("Error"); 
       } 
      ); 


      this.onLoad = function(){ 
       return contactPromise.promise; 
      }; 

    } 
}]); 

Si j'imprime les mêmes valeurs dans le contrôleur, cependant, toutes les valeurs sont undefined:

var newContact = null; 
$scope.openContactModal = function(contactID){ 
    newContact = new Contact(contactID); 
    newContact.onLoad().then(
     function(){ 

      //!!!!!!!!THE FOLLOWING PRINTS ARE ALL UNDEFINED!!!! 
      console.log(newContact.firstName); 
      console.log(newContact.lastName); 
      console.log(newContact.phone); 
      console.log(newContact.fax); 

      $('#myModal').modal('show'); 
     }, 
     function(){ 
      //loading Error 

     } 
    ); 
    $scope.newContact = newContact; 
}; 

Cette est étrange. Il semble une sorte de problème de synchronisation: -/pour être complet ici est une pièce d'exemple du modal:

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> 
    <div class="modal-dialog modal-sm"> 
     <div class="modal-content"> 
      <div class="modal-header"> 
       <h2>Contact</h2> 
      </div> 
      <div class="modal-body"> 
       <label> 
        Name 
        <input class="form-control" id="new_contact_name" data-ng-model="newContact.firstName" placeholder="Name"> 
       </label> 
       <!-- ...and so on --> 
      </div> 
     </div> 
     <div class="modal-footer"> 
      <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> 
      <button type="button" class="btn btn-primary" data-dismiss="modal" data-ng-click="createContact()">Crea</button> 
     </div> 
    </div> 
</div> 

+0

est 'newContact.onLoad()' correct? – dmullings

+1

Oui, c'est une fonction qui renvoie une promesse angulaire. Le modal est affiché correctement à la fin de l'appel Ajax et le Json récupéré contient les bonnes valeurs, mais ces valeurs ne sont pas des «données bidirectionnelles liées» à la vue. – superpuccio

+1

Comment fonctionne votre modem? Est-ce que son contrôleur partage l'objet '$ scope' que vous remplissez avec' newContact'? – Palpatim

Répondre

0

Finalement, j'ai trouvé l'erreur. Ce fut une erreur de la mienne et il ne fait pas partie AngularJS, mais Javascript: vous remarquerez que, dans le service de contact, je l'ai fait:

//the Ajax call  
var metacontact = ContactDBServices.find({ID:contactID}, 
    function(){ 
     this.ID = contactID; 
     this.firstName = metacontact.contact_name; 
     this.lastName = metacontact.contact_last_name; 
     this.phone = metacontact.contact_phone; 
     this.fax = metacontact.contact_fax; 
     this.mobile = metacontact.contact_mobile; 
     this.email = metacontact.contact_email; 
     this.web = metacontact.contact_web; 

    }, 
    function(){ 
     contactPromise.reject("Error"); 
    } 
); 

clairement, l'écriture this. dans la fonction de rappel, je n'a pas affecté les valeurs Contact, mais les attributs de la fonction! Pour résoudre ce problème que je devais changer le rappel de cette façon:

//the Ajax call  
var metacontact = ContactDBServices.find({ID:contactID}, 
    function(){ 
     self.ID = contactID; 
     self.firstName = metacontact.contact_name; 
     self.lastName = metacontact.contact_last_name; 
     self.phone = metacontact.contact_phone; 
     self.fax = metacontact.contact_fax; 
     self.mobile = metacontact.contact_mobile; 
     self.email = metacontact.contact_email; 
     self.web = metacontact.contact_web; 

    }, 
    function(){ 
     contactPromise.reject("Error"); 
    } 
); 

var self = this; 

en dehors du rappel.

Questions connexes