J'essaie de lier une promesse à une vue. Je ne sais pas si vous pouvez le faire directement, mais c'est ce que je tente de faire. Des idées que je fais mal?
Remarque: la source est un peu artificielle avec le délai d'attente et utilise des données statiques, mais cela facilite le diagnostic du code.
EDIT: JSFiddle Page: http://jsfiddle.net/YQwaf/27/
EDIT: SOLUTION: Il s’est avéré que vous pouvez lier directement des promesses. J'ai eu deux problèmes avec mon code d'origine:
HTML:
<div ng:controller="addressValidationController">
Region Code <select ng:model="regionCode" ng:options="r.code as r.name for r in getRegions()"/>
Country Code<select ng:model="countryCode"><option value="US">United States</option><option value="CA">Canada</option></select>
</div>
JS:
function addressValidationController($scope, $q) {
var regions = {
US: [{code: 'WI',name: 'Wisconsin'}, {code: 'MN',name: 'Minnesota'}],
CA: [{code: 'ON',name: 'Ontario'}]
};
$scope.getRegions = function () {
var deferred = $q.defer();
setTimeout(function () {
var countryRegions = regions[$scope.countryCode];
console.log(countryRegions);
if(countryRegions === undefined) {
deferred.resolve([]);
} else {
deferred.resolve(countryRegions);
}
}, 1000);
return deferred.promise;
};
}
WARNING: cette réponse était exacte au moment de sa rédaction, mais à partir de la version 1.2, le moteur de gabarit angulaire ne gère pas les promesses de manière transparente! - @Malvolio
Oui, le moteur de gabarit (et les expressions) traitent les promesses de manière transparente, mais j'attribuerais la promesse à une propriété d'étendue dans le contrôleur et n'appellerais pas à chaque fois une fonction qui renvoie une nouvelle promesse (je pense que c'est votre problème, la promesse résolue est perdue, la promesse est retournée à chaque fois).
JSFiddle: http://jsfiddle.net/YQwaf/36/
HTML:
<div ng:controller="addressValidationController">
Region Code <select ng:model="regionCode" ng:options="r.code as r.name for r in regions"/>
Country Code<select ng:model="countryCode"><option value="US">United States</option><option value="CA">Canada</option></select>
</div>
JS:
function addressValidationController($scope, $q, $timeout) {
var regions = {
US: [{
code: 'WI',
name: 'Wisconsin'},
{
code: 'MN',
name: 'Minnesota'}],
CA: [{
code: 'ON',
name: 'Ontario'}]
};
function getRegions(countryCode) {
console.log('getRegions: ' + countryCode);
var deferred = $q.defer();
$timeout(function() {
var countryRegions = regions[countryCode];
if (countryRegions === undefined) {
console.log('resolve empty');
deferred.resolve([]);
} else {
console.log('resolve');
deferred.resolve(countryRegions);
}
}, 1000);
return deferred.promise;
};
$scope.regions = [];
// Manage country changes:
$scope.$watch('countryCode', function(countryCode) {
if (angular.isDefined(countryCode)) {
$scope.regions = getRegions(countryCode);
}
else {
$scope.regions = [];
}
});
}
Depuis Angular 1.2, vous ne pouvez plus utiliser directement les promesses dans les modèles .
Au lieu de cela, vous devez placer le résultat dans $scope
dans then
, comme vous le feriez normalement - pas de magie.
Pour contourner temporairement l’ancien comportement, vous pouvez appeler
$parseProvider.unwrapPromises(true)
mais cette fonctionnalité sera supprimée plus tard, alors ne comptez pas dessus.
À partir de la version angulaire 1.3 - $parseProvider.unwrapPromises(true)
ne fonctionnera plus .
Au lieu de cela, vous devriez ouvrir les promesses directement:
myApiMethod().then(function(value){
$scope.item = value;
});
Notez que le déballage des promesses fonctionnera toujours avec ngResource comme d’habitude.
renvoyer une référence à la variable scope contenant la liste devrait suffire.
function addressValidationController($scope,$timeout) {
var regions = {
US: [{code: 'WI',name: 'Wisconsin'}, {code: 'MN',name: 'Minnesota'}],
CA: [{code: 'ON',name: 'Ontario'}]
};
$scope._regions = [];
$scope.getRegions = function () {
$timeout(function () {
var countryRegions = regions[$scope.countryCode];
console.log(countryRegions);
if(countryRegions === undefined) {
$scope._regions = []
} else {
$scope._regions = countryRegions
}
}, 1000);
return $scope._regions;
};
}