wake-up-neo.com

Angularjs übergibt Objekt an Direktive

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. 

29
winkerVSbecks

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.

40
Mark Rajcok

sie können auch verwenden 

scope.walks.$promise.then(function(walks) {
    if(walks) {
      console.log(walks);
    }
  });
11
sawe

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>
3
Niko

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));
    }
  }
});
2
Elise Chant

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
     }
   });
  });
 });
0
clagccs