web-dev-qa-db-ja.com

オブジェクトをディレクティブに渡すAngularjs

角度のある初心者はこちら。オブジェクトをディレクティブに渡すときに何が間違っているのかを理解しようとしています。

ここに私の指示があります:

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

そして、これは私がディレクティブを呼び出すテンプレートです:

<div walkmap="store.walks"></div>

store.walksはオブジェクトの配列です。

これを実行すると、scope.walksundefinedとして記録しますが、scopeはScopeとして問題なく記録し、探しているすべてのデータを含むwalks子さえも記録します。

この正確な方法は以前私のために働いていたので、私はここで何が間違っているのか分かりません。

編集:

必要なすべてのコードを含むプランカーを作成しました: http://plnkr.co/edit/uJCxrG

ご覧の通り、{{walks}}はスコープで使用可能ですが、未定義としてログに記録しているリンク関数でアクセスする必要があります。

29
winkerVSbecks

_$resource_を使用してデータを取得しているため、データが利用可能になる前にディレクティブのリンク関数が実行されているため(_$resource_の結果は非同期であるため)、リンク関数で初めて_scope.walks_は空/未定義です。ディレクティブテンプレートには_{{}}_ sが含まれているため、Angular=はwalksに_$watch_を設定します。そのため、_$resource_がデータを入力すると、 _$watch_トリガーと表示の更新これは、コンソールにウォークデータが表示される理由も説明しています-リンクをクリックしてスコープを展開するまでに、データが入力されます。

問題を解決するには、リンク関数_$watch_で、データがいつ利用可能になるかを確認します。

_scope.$watch('walks', function(walks) {
   console.log(scope.walks, walks);
})
_

本番コードでは、未定義にならないように注意してください。

_scope.$watch('walks', function(walks) {
  if(walks) { ... }
})
_

更新:バージョンAngularで_$resource_がプロミスをサポートしている場合、@ saweの回答も参照してください。

40
Mark Rajcok

あなたも使うことができます

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

別の解決策は、ControllerAsをディレクティブに追加して、ディレクティブの変数にアクセスできるようにすることです。

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

次に、ビューで、controllerAs変数を使用して変数を渡します。

<div walkmap="store.walks" ng-init="dir.store.walks"></div>
3
Niko

試してください:

<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

宣言された$ scope.storeはコントローラーからは見えません。関数内で宣言します。したがって、その関数のスコープ内でのみ見えます。外部で宣言する必要があります。

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