2012-12-29 10 views
9

AngularJS docs say:AngularJS promettono

$ q promesse sono riconosciuti dal motore di template in angolare, il che significa che in modelli che è possibile trattare le promesse collegate a un ambito come se fossero i valori risultanti.

Quindi qualcuno potrebbe spiegare il motivo per cui questo fiddle non funziona? Non è possibile modificare il valore del campo di testo. Ma l'assegnazione di promesse che il servizio $ http restituisce a un campo di ambito funziona come un incantesimo.

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

Potrebbe mostrarmi come hai assegnato una promessa restituita da $ http che ha funzionato nel modo desiderato? – Dogbert

+0

@Dogbert, Ecco lo pseudocodice per illustrare di cosa stavo parlando: '$ scope.item = $ http ({metodo: 'post', url: '/ find/my/item /'}) .then (funzione (risposta) { return response.item; }); ' Un altro esempio che utilizza l'approccio $ risorse può essere trovato in questo [tutorial] (http://docs.angularjs.org/tutorial/step_11). A partire dalla riga: 'Nota come in PhoneListCtrl abbiamo sostituito ... con $ scope.phones = Phone.query();' –

+0

Oops, appena creato [esempio di prova] (http://plnkr.co/edit/ VP1Td3WtdM0E7n5HJH3W? P = anteprima), e sembra non funzionare con alcuna promessa –

risposta

14

È necessario utilizzare la funzione di allora() sull'oggetto promessa:

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

Nel tuo caso Non penso che tu abbia bisogno di un professionista mise. Il sistema di controllo $ di Angular si prenderà cura delle cose. 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

So cosa intendi. Ho aggiornato la mia risposta. Devi lasciare che l'angolare si prenda cura di esso (lo farà automaticamente con il suo sistema $ watch). – asgoth

+0

Il secondo esempio che hai fornito non sembra più semplice del primo;) Inoltre, non funzionerà come previsto, perché $ http.get() verrà risolto con json che rappresenta _item_, non solo _title_ So ' this.getItem(). then (function (result) { $ scope.item = result; }); 'sembra abbastanza accettabile (ho appena cambiato this.item = result a $ scope.item = result) –

+0

Ah, infatti che questo avrebbe dovuto essere lo scopo. Lo cambierò in modo che tu possa accettarlo. – asgoth

1

Credo che la ragione per la vostra prima violino non funziona è perché si sono essenzialmente rilegare proprietà ambito item ad una promessa. Quando si tenta di modificare il valore digitando nel campo di testo, l'operatore rileva l'attività, quindi riassegna/reimposta il valore di item sul risultato della promessa (che non è stata modificata).

La soluzione fornita da @asgoth imposta/assegna il valore di item una volta, quando la promessa viene risolta. Non c'è nessuna connessione in corso qui (ad esempio, item non è vincolato alla promessa), pertanto l'alterazione del valore tramite la casella di testo altera il valore.

-1

Come ha detto @Mark, qui puoi trovare uno Working Example del tuo snippet.

In pratica si restituiva un oggetto e non si associava il modello stesso.

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

L'ultima riga del tuo JavaScript dovrebbe probabilmente essere semplicemente 'this.getItem();'. –