Eckiger Neuling hier. Ich versuche herauszufinden, was bei der Weitergabe von Objekten an Anweisungen schief läuft.
hier ist meine Anweisung:
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);
}
};
});
und das ist die Vorlage, in der ich die Direktive nenne:
<div walkmap="store.walks"></div>
store.walks
ist ein Array von Objekten.
Wenn ich das ausführen, protokolliert scope.walks
als undefined
, während scope
als Scope einwandfrei protokolliert und sogar ein walks
-Kind mit allen Daten enthält, nach denen ich suche.
Ich bin mir nicht sicher, was ich hier falsch mache, weil diese Methode zuvor für mich funktioniert hat.
BEARBEITEN:
Ich habe einen Plunker mit dem erforderlichen Code erstellt: http://plnkr.co/edit/uJCxrG
Wie Sie sehen, ist der {{walks}}
im Geltungsbereich verfügbar, aber ich muss in der Link-Funktion darauf zugreifen, wo er immer noch als undefiniert protokolliert wird.
Da Sie $resource
zum Abrufen Ihrer Daten verwenden, wird die Verknüpfungsfunktion der Direktive ausgeführt, bevor die Daten verfügbar sind (da die Ergebnisse von $resource
asynchron sind). Daher ist das erste Mal in der Verknüpfungsfunktion scope.walks
leer/undefiniert. Da Ihre Direktionsvorlage {{}}
s enthält, richtet Angular einen $watch
für walks
ein. Wenn also $resource
die Daten auffüllt, werden $watch
ausgelöst und die Anzeige aktualisiert. Dies erklärt auch, warum Sie die Wanderungsdaten in der Konsole sehen. Wenn Sie auf den Link klicken, um den Bereich zu erweitern, werden die Daten gefüllt.
Um Ihr Problem zu lösen, können Sie in Ihrer Linkfunktion $watch
wissen, wann die Daten verfügbar sind:
scope.$watch('walks', function(walks) {
console.log(scope.walks, walks);
})
Achten Sie in Ihrem Produktionscode darauf, dass es undefiniert ist:
scope.$watch('walks', function(walks) {
if(walks) { ... }
})
Update: Wenn Sie eine Angular-Version verwenden, in der $resource
Versprechungen unterstützt, lesen Sie auch die Antwort von @sawe.
sie können auch verwenden
scope.walks.$promise.then(function(walks) {
if(walks) {
console.log(walks);
}
});
Eine andere Lösung wäre, ControllerAs
zur Direktive hinzuzufügen, über die Sie auf die Variablen der Direktive zugreifen können.
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);
}
};
});
Übergeben Sie dann in Ihrer Ansicht die Variable mit der Variablen controllerAs
.
<div walkmap="store.walks" ng-init="dir.store.walks"></div>
Versuchen:
<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));
}
}
});
ihr deklarierter $ scope.store ist auf dem Controller nicht sichtbar. Sie müssen ihn innerhalb einer Funktion deklarieren.
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
}
});
});
});