Débutant angulaire ici. J'essaie de comprendre ce qui ne va pas en passant des objets à des directives.
voici ma directive:
app.directive('walkmap', function() {
return {
restrict: 'A',
transclude: true,
scope: { walks: '=walkmap' },
template: '<div id="map_canvas"></div>',
link: function(scope, element, attrs)
{
console.log(scope);
console.log(scope.walks);
}
};
});
et voici le modèle où j'appelle la directive:
<div walkmap="store.walks"></div>
store.walks
est un tableau d'objets.
Lorsque je lance ceci, scope.walks
enregistre en tant que undefined
tandis que scope
se connecte correctement en tant que Scope et a même un enfant walks
avec toutes les données que je recherche.
Je ne suis pas sûr de ce que je fais mal ici parce que cette méthode exacte a déjà fonctionné pour moi.
MODIFIER:
J'ai créé un plunker avec tout le code requis: http://plnkr.co/edit/uJCxrG
Comme vous pouvez le constater, le {{walks}}
est disponible dans l'étendue, mais je dois y accéder via la fonction de liaison où il est toujours enregistré comme non défini.
Puisque vous utilisez $resource
pour obtenir vos données, la fonction de liaison de la directive est en cours d'exécution avant que les données ne soient disponibles (car les résultats de $resource
sont asynchrones), de sorte que la première fois dans la fonction de liaison scope.walks
sera vide/indéfinie. Puisque votre modèle de directive contient {{}}
s, Angular configure un $watch
sur walks
. Ainsi, lorsque $resource
remplit les données, les déclencheurs $watch
et l'affichage sont mis à jour. Cela explique également pourquoi vous voyez les données de parcours dans la console: lorsque vous cliquez sur le lien pour développer l'étendue, les données sont renseignées.
Pour résoudre votre problème, dans votre fonction de liaison $watch
pour savoir quand les données sont disponibles:
scope.$watch('walks', function(walks) {
console.log(scope.walks, walks);
})
Dans votre code de production, veillez simplement à ce qu'il ne soit pas défini:
scope.$watch('walks', function(walks) {
if(walks) { ... }
})
Mise à jour: / Si vous utilisez une version de Angular dans laquelle $resource
prend en charge les promesses, voir aussi la réponse de @ sawe.
vous pouvez aussi utiliser
scope.walks.$promise.then(function(walks) {
if(walks) {
console.log(walks);
}
});
Une autre solution serait d’ajouter ControllerAs
à la directive par laquelle vous pouvez accéder aux variables de la directive.
app.directive('walkmap', function() {
return {
restrict: 'A',
transclude: true,
controllerAs: 'dir',
scope: { walks: '=walkmap' },
template: '<div id="map_canvas"></div>',
link: function(scope, element, attrs)
{
console.log(scope);
console.log(scope.walks);
}
};
});
Et ensuite, à votre avis, transmettez la variable à l'aide de la variable controllerAs
.
<div walkmap="store.walks" ng-init="dir.store.walks"></div>
Essayer:
<div walk-map="{{store.walks}}"></div>
angular.module('app').directive('walkMap', function($parse) {
return {
link: function(scope, el, attrs) {
console.log($parse(attrs.walkMap)(scope));
}
}
});
votre $ scope.store déclaré n'est pas visible depuis le contrôleur ... vous le déclarez à l'intérieur d'une fonction ... pour qu'il ne soit visible que dans le cadre de cette fonction, vous devez déclarer ceci en dehors
app.controller('MainCtrl', function($scope, $resource, ClientData) {
$scope.store=[]; // <- declared in the "javascript" controller scope
ClientData.get({}, function(clientData) {
self.original = clientData;
$scope.clientData = new ClientData(self.original);
var storeToGet = "150-001 KT";
angular.forEach(clientData.stores, function(store){
if(store.name == storeToGet ) {
$scope.store = store; //declared here it's only visible inside the forEach
}
});
});
});