2012-12-29 1 views
9

AngularJS docs say:AngularJS promettent

promesses q $ sont reconnus par le moteur de templating dans angulaire, ce qui signifie que dans les modèles que vous pouvez traiter les promesses attachées à un champ d'application comme si elles étaient les valeurs qui en résultent.

Donc, quelqu'un pourrait expliquer s'il vous plaît la raison pour laquelle cette fiddle ne fonctionne pas? Il n'est pas possible de changer la valeur du champ de texte. Mais l'attribution de promesses que le service $ $ renvoie à un champ d'étendue fonctionne comme un charme.

Controller:

function MyController($scope, $q, $timeout) { 
    this.getItem = function() { 
     var deferred = $q.defer(); 
     deferred.resolve({ 
      title: 'Some title' 
     }); 
     return deferred.promise; 
    }; 

    $scope.item = this.getItem(); 
} 

Html:

<input type="text" ng-model="item.title"> 
+0

Pourriez-vous me montrer comment vous avez attribué une promesse retournée par $ http qui a fonctionné comme vous le souhaitiez? – Dogbert

+0

@Dogbert, Voici un pseudo-code pour illustrer de quoi je parlais: '$ scope.item = $ http ({méthode: 'post', url: '/ find/mon/item /'}) .then (function (response) { return response.item; }); ' Un autre exemple utilisant l'approche $ resource peut être trouvé dans ce [tutorial] (http://docs.angularjs.org/tutorial/step_11). À partir de la ligne: 'Notez comment dans PhoneListCtrl nous avons remplacé ... avec $ scope.phones = Phone.query();' –

+0

Oups, juste créé [exemple de test] (http://plnkr.co/edit/ VP1Td3WtdM0E7n5HJH3W? P = preview), et il semble ne pas fonctionner avec aucune promesse –

Répondre

14

Vous devez utiliser la fonction puis() sur l'objet de promesse:

this.getItem().then(function(result) { 
    $scope.item = result; 
}); 

Dans votre cas Je ne pense pas que vous ayez besoin d'un pro mise Le système de surveillance d'Angular prendra soin de tout. Just return an object in your function, not a primitive type:

this.getItem = function() { 
    var item = {}; 

    // do some async stuff 
    $http.get(...).success(function(result) { 
     item.title = result; 
    }); 
    return item; 
}; 

$scope.item = this.getItem(); 
+0

Je sais ce que vous voulez dire. J'ai mis à jour ma réponse. Vous devez laisser angulaire en prendre soin (il le fera automatiquement avec son système de surveillance $). – asgoth

+0

Le deuxième exemple que vous avez donné ne semble pas plus simple que le premier;) En outre, cela ne fonctionnera pas comme prévu, car $ http.get() sera résolu avec json représentant _item_, pas seulement _title_ So ' this.getItem(). then (function (resultat) { $ scope.item = result; }); 'semble tout à fait acceptable (je viens de changer this.item = result pour $ scope.item = result) –

+0

Ah, en effet que cela aurait dû être la portée. Je vais le changer pour que vous puissiez l'accepter. – asgoth

1

Je crois que la raison pour laquelle votre premier violon ne fonctionne pas parce que vous liez essentiellement la propriété de portée item à une promesse. Lorsque vous essayez de modifier la valeur en tapant dans le champ de texte, angular remarque l'activité, puis réaffecte/réinitialise la valeur de item au résultat de la promesse (qui n'a pas changé).

La solution fournie par @asgoth définit/affecte la valeur item une fois, lorsque la promesse est résolue. Il n'y a pas de liaison en cours ici (c'est-à-dire que item n'est pas liée à la promesse), donc modifier la valeur via la zone de texte modifie la valeur.

-1

C'est comme @Mark dit, ici vous pouvez trouver un Working Example de votre extrait.

Fondamentalement, vous retourniez un objet et ne liez pas le modèle lui-même.

$timeout(function(){ 
    $scope.item = { 
     title: 'Some title' 
    }; // Apply the binding 
    deferred.resolve(); // Resolve promise 
},2000); // wait 2 secs   
+0

La dernière ligne de votre JavaScript devrait probablement être 'this.getItem();'. –