1

基本的に、2 つのディレクティブがあります。

angular.module("maineMap")
.directive("ngMap", ["APPCONFIG", "Map", function(config, Map){
       //D3 map drawing functionality based on data from $resource call
       return {
        restrict : "E",
        transclude : true,
        scope : {
            mapData : '='
        },
        link : function(scope, el, attrs){
                   }
        };
    }])
    .directive("donutChart", function(){
    return {
        restrict : "E",
        link : function(scope, el, attrs){
                    }
            }
    });

そしてコントローラー

angular.module("maineMap")
.controller('MapCtrl', ['$scope','Map', function($scope, Map{
    $scope.mapData = Map.mapData()  
                        .query();

    $scope.mapData.$promise.then(function(results){
        $scope.mapData = results;
        console.log($scope.mapData);
    });

}]);

JSONファイルを取得するための実装ですMap$resource

私の問題は、コントローラー呼び出しの前にディレクティブ機能が実行されていることです。つまりmapData、ディレクティブ内で のいくつかのプロパティを呼び出すと、それらはすべて undefined を返し、対応するエラー メッセージがコンソールに表示されます。ただし、エラー出力の直後に、$resource実装からのデータ フェッチが実行され、コンソールに出力されます。

を置き換えて$promise、のみに依存することに注意してください

$scope.mapData = Map.mapData()  
                        .query();

次に、ディレクティブに$scope.mapData表示されますが、表示されません。<donut-chart><ng-map>

この種の構造を考えると、コントローラーがデータをロードするまでディレクティブ機能を遅らせるにはどうすればよいでしょうか?

4

2 に答える 2

0

以下の実行順序:

<div ng-controller="controller">
    <outer>
      <inner></inner>
      <inner></inner>
    </outer>
</div>

だろう:

  1. コンパイル (内部)
  2. コンパイル (内部)
  3. コンパイル(外側)
  4. コントローラ
  5. コントローラー(アウター)
  6. コントローラー(インナー)
  7. リンク(内側)
  8. コントローラー(インナー)
  9. リンク(内側)
  10. リンク(外側)

したがって、コントローラーは、ディレクティブのリンクが発生する前にスコープを明確に設定します。もちろん、スコープが非同期関数で設定されていない限り。ただし、ディレクティブはスコープ値を処理できる必要があります。ディレクティブはundefined、それ以外の場合、どのコントローラーで動作しているかを気にしない (おそらくすべきではない)requiresためです。

于 2014-10-03T14:22:26.053 に答える
0

この問題にはjoakimbiのソリューションを使用しました。具体的には、ngRoute依存関係を追加し、resolveプロパティを使用して、含まれているプロミスがビューを表示する前にデータ フェッチを実行するようにします。

更新されたサービス:

angular.module("maineMap")
.factory("MapService", ["$http", "$log", "$q", "appConfig", function($http, $log, $q, appConfig){
    var mapPaths, mapPromise, 
        cityPositions, cityPromise;

    return {
        getMapPaths : function(){

            mapPromise = $http.get(appConfig.maineData)
                                .success(function(data){
                                    mapPaths = data;
                                });

            return {
                getData : function(){
                    return mapPaths;
                },
                setData : function(data){
                    mapPaths = data;
                },
                promise : mapPromise
            };
        },
        getCityPositions : function() { ... }
   };
}]);

resolve プロパティで promise を定義する変更されたアプリ初期化子:

angular.module("maineMap", ["ngResource", "ngRoute", "configuration"])
.config(["$routeProvider", function($routeProvider){
    $routeProvider.when("/", {
        templateUrl : "views/main.html",
        controller : "MapCtrl",
        resolve : {
            "MapData" : function(MapService){
                return MapService.getMapPaths().promise;
            },
            "CityData" : function(MapService){
                return MapService.getCityPositions().promise;
            }
        }
    });
}]);

ビューの前にデータフェッチが読み込まれる変更されたコントローラー:

angular.module("maineMap")
.controller('MapCtrl', ['$scope','MapService', function($scope, MapService){
    $scope.mapData = MapService.getMapPaths().getData();
    $scope.cityData = MapService.getCityPositions().getData();
    $scope.currentCounty = {};
    console.log("MapData: " + $scope.mapData);
}]);

この結果、ディレクティブのタグがビュー テンプレート内で処理される前に、データ フェッチが実行され、結果がスコープに保存され、ディレクティブで使用できるようになります。

Martin Atkinsによって提案された別のオプションでは、データをangular.constant()変数にロードしていました。このアプリケーションをいくつかのビューに拡張することを計画しているので、 promisengRouteと組み合わせるresolveことが適切な解決策でした。

于 2014-10-07T12:30:09.737 に答える