2016-09-27 23 views
0

角度&のディレクティブを使用して、データベースのデータからベクターマップを作成しようとしています。

私はデータベースのデータで埋められた米国のsvgベクトルマップを表示する必要がある角度ダッシュボードのWebページを持っています。私はthis tutorialに従っていますが、すべてうまくいきますが、チュートリアルではハードコードされた値がマップに渡されます。私はデータベースの値を受け入れるためにこれを修正する必要があります。&それは私が問題を抱えているところです。どのように私のデータベースに電話をかけ、それらの値を指令を使ってマップに戻すことができますか?

私は、このディレクティブと私の初めての経験ですが、$http.get呼び出しが指示した後に発生したかのように見えるので、私は遅すぎる私のDBデータを返すよまだ角度&に新たなんです。ここに私のコードは次のとおりです。ここで

App.js

、私はこのマップ機能の両方のディレクティブを使用しています。このすべてが正常に動作します:

var app = angular.module('dashboardApp', ['ngRoute', 'angularjs-dropdown-multiselect']); 

app.controller('dashboardController', DashboardController); 

app.directive('svgMap',function ($compile) { 
return { 
    restrict: 'A', 
    templateUrl: '/Content/Images/Blank_US_Map.svg', 
    link: function (scope, element, attrs) { 
     var regions = element[0].querySelectorAll('path'); 
     angular.forEach(regions, function (path, key) { 
      var regionElement = angular.element(path); 
      regionElement.attr("region", ""); 
      regionElement.attr("dummy-data", "dummyData"); 
      $compile(regionElement)(scope); 
     })    
    } 
} 
}); 

app.directive('region', function ($compile) {  
return { 
    restrict: 'A', 
    scope: { 
     dummyData: "=" 
    }, 
    link: function (scope, element, attrs) {    
     scope.elementId = element.attr("id"); 
     scope.regionClick = function() {     
      alert(scope.dummyData[scope.elementId].value); 
     }; 
     element.attr("ng-click", "regionClick()"); 
     element.attr("ng-attr-fill", "{{dummyData[elementId].value | map_color}}"); 
     element.removeAttr("region"); 
     $compile(element)(scope); 
    } 
} 
}); 

DashboardController.js

私の問題がある場所です。ここでは、データベースから$http.get経由でデータを返します。私は現在、このhttp.get &の外で私の$scope.createDummyData機能を持っています。しかし、そのコードを私の$http.getの中に置くと、データが入力されません。そして、それは私の問題だ:

var DashboardController = function ($scope, $http) { 
$http.get('/Account/GetDashboardDetails') 
    .success(function (result) { 

     //need to place my $scope.createDummyData inside here 

    }) 
    .error(function (data) { 
     console.log(data); 
    }); 

var states = ["AL", "AK", "AS", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FM", "FL", "GA", "GU", "HI", "ID", "IL", 
     "IN", "IA", "KS", "KY", "LA", "ME", "MH", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", 
     "NY", "NC", "ND", "MP", "OH", "OK", "OR", "PW", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VI", "VA", 
     "WA", "WV", "WI", "WY"]; 
$scope.createDummyData = function() { 
    var dataTemp = {}; 
    angular.forEach(states, function (state, key) { 
     dataTemp[state] = { value: Math.random() } 
    }); 
    $scope.dummyData = dataTemp; 
}; 
$scope.createDummyData(); 
}; 

HTML

最後に、ここに私のhtmlです。私はここで何が私の問題に関係感じることはありませんが、私はとにかくそれを含め、念のため:

<div class="container"> 
    <div svg-map class="col-md-8 col-sm-12 col-xs-12" style="height:350px;"></div> 
    <p> 
     <button ng-click="createDummyData()" class="btn btn-block btn-default">Create Dummy Data</button> 
    </p> 
    <div class="regionlist"> 
     <div ng-repeat="(key,region) in dummyData"> 
      <div>{{key}}</div> 
      <div>{{region.value | number}}</div> 
     </div> 
    </div> 
</div> 

はどのようにして、データベースのデータを介して、私のマップを埋めるについて行くことができますか?

おかげ

+0

なぜディレクティブからHTTPコールを作成しないのですか? – user2085143

+1

svg-mapを含むdivの周りにng-ifをラップしてみてください。最初にng-if変数をfalseに設定し、バックエンドからデータを取得してdummydataを設定したら、ng-if変数をtrueに設定します。テンプレートのレンダリングが開始されます。 –

+0

'createDummyData'メソッドで' $ scope'にダミーデータをどのように割り当てるかを示しています。 _サーバーから返されたデータに対して同じロジックを実装する方法は? –

答えて

0

これはあなたが正確に探しているが、役立つかもしれないものであるかどうかわかりません。

データを取得するためのサービスを作成します(HTTPの/ Account/GetDashboardDetailsが状態のリストを返すと仮定しています)。次に、コントローラのサービスを呼び出します。呼び出しが完了したら、create dummyDataFunctionを呼び出します。 $http.get XHRが応答を受信する前に

// Service 

angular 
    .module('dashboardApp') 
    .service('$dataService', dataService); 

dataService.$inject = ['$http'] 

function dataService() { 

    var service = { 

    getData : getData 

    } 

    return service; 

    ////////// 

    function getData() { 
    return $http.get('/Account/GetDashboardDetails') 
    .then(function (result) { 
     return result; 
    },function(error) { 
     return error; 
    }) 
    } 

} 


// Controller 

var DashboardController = function ($scope,$dataService) { 

    $scope.dummyData = []; 
    activate(); 

    ///////// 

    function activate() { 
    $dataService.getData() 
     .then(function(states){ 

     var dataTemp = {}; 

     angular.forEach(states, function (state, key) { 
      dataTemp[state] = { value: Math.random() } 
     }); 

     $scope.dummyData = dataTemp; 

     },function(error) { 
     console.log(error); 
     }); 
    } 

}; 
0

ディレクティブのリンク機能が実行されます。一つのアプローチは、データを待つ$watchを使用することです:

app.directive('region', function ($compile) {  
    return { 
     restrict: 'A', 
     scope: { 
      dummyData: "=" 
     }, 
     link: function (scope, element, attrs) {    
      scope.elementId = element.attr("id"); 
      scope.regionClick = function() {     
       alert(scope.dummyData[scope.elementId].value); 
      }; 
      element.attr("ng-click", "regionClick()"); 
      element.attr("ng-attr-fill", "{{dummyData[elementId].value | map_color}}"); 
      element.removeAttr("region"); 
      //Use $watch to wait for data 
      scope.$watch("::dummyData", function(value) { 
       if (value) { 
        $compile(element)(scope); 
       }; 
      }); 
     } 
    } 
}); 

上記の例では$compile文は一度だけ実行されるように、ウォッチ式はone-time bindingを使用しています。データの変更ごとに要素を再コンパイルしたい場合は、それがより複雑になります。

$watchの詳細については、あなたがこれまでにHTTPリクエストをプレゼントする前に自分のsvgMapディレクティブのlink機能が道と呼ばれている場合、それは問題ではありませんAngularJS $rootscope.Scope API Reference - $watch

0

参照してください。

あなたが持っているのは、svgMapディレクティブが、外側コントローラスコープからdummyDataにバインドされたregionディレクティブを動的に作成していることです。ビーイング

dummyDataからは角がすでにバインドされたプロパティの監視人を登録したことを意味し結合しました。言い換えれば、これは、プロパティが実際に他の場所、すなわち親コントローラに設定される前であっても、このバインディングが存在することを意味する。

$scope.dummyDataには、サーバーから返されるデータが正しく割り当てられていない可能性があります。

ご質問のコードからgetリクエストでsuccessハンドラを呼び出し、result変数に返信してください。ただし、レスポンスからデータを取得する方法については言及していません。だから、私はあなたがsuccess()コールバックと.then()コールバックからの応答を混同しているかもしれない数える:

.success()コールバックの場合は

.then()成功コールバックの場合は

$http.get('/Account/GetDashboardDetails') 
.success(function (result) { 
    $scope.dummyData = result // data exists in the `result` itself 
}) 

$http.get('/Account/GetDashboardDetails') 
.then(function (response) { 
    $scope.dummyData = response.data; // data is wrapped in `data` 
}) 

上記のような場合ではなく、サーバーから返されたデータがスコープに正しく割り当てられていることを確認したら、その部分を$timeout()の中にラップしてみてください。これにより$scope.$apply()がトリガーされ、$scope.dummyDataの変更がビューに正しく反映されます。

var DashboardController = function ($scope, $http, $timeout) { 
$http.get('/Account/GetDashboardDetails') 
.success(function (result) { 
    $timeout(function(){ 
     /* Do something here */ 
     $scope.dummyData = result; 
    }); 
}) 
関連する問題