2013-07-09 3 views
9

각도 응용 프로그램 내에 ArcGIS JavaScript API을 사용하려고합니다. 보시다시피 Dojo가 사용됩니다. 그래서,이 같은 각도 지침에서는 ArcGIS를 초기화하는 것을 시도하고있다 :AngularJS + ArcGIS

Uncaught TypeError: Cannot call method 'apply' of null 
: 나는 마우스 휠을 스크롤하여 확대 할 때, 나는이 오류가 있기 때문에이 방법 같은데
link: function (scope, element, attrs) { 
    dojo.require('esri.map'); 
    var init = function() { 
     console.log('dojo is ready'); 
     var map = new esri.Map("map-container", { 
     center: [-111.3797, 56.7266 ], 
     zoom: 16, 
     basemap: "streets" 
     }); 
     map.enableScrollWheelZoom() 

    }; 
    dojo.addOnLoad(init); 
    } 

는 100 % 정확

내 질문에, 각도 응용 프로그램 내에서 ArcGIS 기능을 제대로 삽입하는 방법은 무엇입니까?

답변

12

매우 'AngularJS'스타일 접근 방식은 다음과 같을 것이라고 생각합니다. (바이올린 여기 http://jsfiddle.net/technicolorenvy/2Ke62/4/)

나는 angular-ui-router을 사용하고 싶지만,이 접근법은 Angular의 $routeProvider도 사용할 수 있습니다. 여기에있는 마법은 계속하기 전에 약속이 해결 될 때까지 선택적으로 '대기'하는 해결 객체에 있습니다.

angular.module('webApp', ['ui.router']) 
    // module (app) config 
    .config(function ($stateProvider, $urlRouterProvider) { 

     $urlRouterProvider.otherwise('/map'); 

     $stateProvider.state('map', { 
      url: '/map', 
      template: '<div id="map"></div>', 
      controller: 'MapCtrl', 
      resolve: { 
       promiseObj: function ($q, $rootScope, wish) { 
        var deferred = $q.defer(), 
         deps = { 
          Map: 'esri/map', 
          FeatureLayer: 'esri/layers/FeatureLayer', 
          InfoTemplate: 'esri/InfoTemplate', 
          SimpleFillSymbol: 'esri/symbols/SimpleFillSymbol', 
          SimpleRenderer: 'esri/renderers/SimpleRenderer', 
          SimpleMarkerSymbol: 'esri/symbols/SimpleMarkerSymbol', 
          ScaleDependentRenderer: 'esri/renderers/ScaleDependentRenderer', 
          Color: 'dojo/_base/Color' 
         }; 

        wish.loadDependencies(deps, function() { 
         deferred.resolve(); 
         if (!$rootScope.$$phase) { 
          $rootScope.$apply(); 
         } 
        }); 

        return deferred.promise; 
       } 
      } 
     }); 
    }); 

위에서 볼 수 있듯이

, 우리는 resolve 소품이있는 map 상태를 가지고있다. 그런 다음 ArcGIS/Dojo 종속성을 나타내는 객체를 만들고이를 wish.loadDependencies (아래 참조)에 전달할 수 있습니다.

당신은 당신으로 (모든는 ArcGIS/도장 FNS 직접 전화를, 우리는 모든 종속성이 MapCtrl에 그 후 도장의 require

angular.module('webApp') 
    // service that deals w/ our dojo require 
    .service('wish', function() { 

     // it's not require... it's a wish? 
     var wish = {}; 

     function _loadDependencies(deps, next) { 
      var reqArr = _.values(deps), 
       keysArr = _.keys(deps); 

      // use the dojo require (required by arcgis + dojo) && save refs 
      // to required obs 
      require(reqArr, function() { 
       var args = arguments; 

       _.each(keysArr, function (name, idx) { 
        wish[name] = args[idx]; 
       }); 

       next(); 
      }); 
     } 

     return { 
      loadDependencies: function (deps, next) { 
       _loadDependencies(deps, next); 
      }, 

      get: function() { 
       return wish; 
      } 
     }; 
    }); 

를 통해로드되면 해결됩니다 약속을 반환합니다 q를 할 수 사용 보통은 wish.get()에 의해 반환 된 객체에 첨부되어 있기 때문에 app config에서 생성 된 deps 객체에서 사용한 키에 의해 생성됩니다. 다음 무엇

여기 (https://developers.arcgis.com/en/javascript/jssamples/renderer_proportional_scale_dependent.html) 발견 된 예를

angular.module('webApp') 
    // our map controller 
    .controller('MapCtrl', function ($rootScope, $scope, wish) { 

     var w = wish.get(), 
      greenFill = new w.Color([133, 197, 133, 0.75]), 
      greenOutline = new w.Color([133, 197, 133, 0.25]), 
      layer, 
      markerSym, 
      renderer1, 
      renderer2, 

      CROPS_URL = 'http://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/USA_County_Crops_2007/FeatureServer/0'; 

     $scope.map = new w.Map('map', { 
      center: [-98.579, 39.828], 
      zoom: 4, 
      basemap: 'gray' 
     }); 

     layer = new w.FeatureLayer(CROPS_URL, { 
      outFields: ['STATE', 'COUNTY', 'M086_07', 'AREA'], 
      infoTemplate: new w.InfoTemplate('${COUNTY}, ${STATE}', '<div style="font: 18px Segoe UI">The percentage of the area of the county that represents farmland is <b>${M086_07}%</b>.</div>') 
     }); 
     layer.setDefinitionExpression('AREA>0.01 and M086_07>0'); 


     markerSym = new w.SimpleMarkerSymbol(); 
     markerSym.setColor(greenFill); 
     markerSym.setOutline(markerSym.outline.setColor(greenOutline)); 
     renderer1 = new w.SimpleRenderer(markerSym); 
     renderer1.setProportionalSymbolInfo({ 
      field: 'M086_07', 
      minSize: 1, 
      maxSize: 10, 
      minDataValue: 0, 
      maxDataValue: 100 
     }); 

     //for the second renderer increase the dot sizes and set a backgroundFillSymbol 
     renderer2 = new w.SimpleRenderer(markerSym); 
     renderer2.setProportionalSymbolInfo({ 
      field: 'M086_07', 
      minSize: 5, 
      maxSize: 15, 
      minDataValue: 0, 
      maxDataValue: 100 
     }); 

     layer.setRenderer(new w.ScaleDependentRenderer({ 
      rendererInfos: [{ 
       'renderer': renderer1, 
        'minScale': 50000000, 
        'maxScale': 10000000 
      }, { 
       'renderer': renderer2, 
        'minScale': 0, 
        'maxScale': 5000000 
      }] 
     })); 

     $scope.map.addLayer(layer); 
    }); 

위의 코드를 보여주는 작업 바이올린의 수정 된 버전, 난 당신의 솔루션을 좋아하지만 작은 문제가 여기 http://jsfiddle.net/technicolorenvy/2Ke62/4/

+0

발견된다. 각도 번역을 사용하고 있으며 "//js.arcgis.com/3.14"에서 init.js를로드하는 데 초당 시간이 걸리므로 각도 변환이 렌더링 된 텍스트 대신 {{ 'something'| translate}}로 표시됩니다 'require'를로드하기 위해 init.js가로드 될 때까지. 위시 서비스에서 필수 종속성을 제거하는 방법을 알고 있습니까? – laitha0

+0

나는 이것을 프리 로더 또는 '데이터로드'플래그를 통해 UI에서 처리합니다. 문제와 가능한 해결책에 대한 꽤 괜찮은 설명 http://www.code-hound.com/add-a-preloader-to-your-website-using-angularjs/ – technicolorenvy

+0

고마워, 나는 이것을 시험해 보겠다. – laitha0

7

지도를 지시문 요소 안에 작성하려는 것 같습니다. 이것은 합법적 인 사용이지만 Dojo의 AMD 로더를 사용하여 모듈을로드 한 다음 모든 도장의 장점이 준비된 후 bootstrap 각도 응용 프로그램을 사용할 수 있도록합니다.

저는 최근에 Angular/Esri dev에 글을 작성했으며 샘플 프로젝트의 소스 코드는 here입니다.

내가 실제로하는 일은 컨트롤러에서 맵을 빌드하는 것이지만 프로세스는 지시문에서 빌드하는 것과 유사해야합니다.

define([ 
    'angular', 
    'esri/map' 
], function(angular, Map) { 
    function mapConfigs() { 
     return { 
      basemap: 'streets', 
      center: [-118.1704035141802,34.03597014510993], 
      zoom: 15 
     }; 
    } 
    function mapGen(elem) { 
     return new Map(elem, mapConfigs()); 
    } 
    function AppController($scope) { 
     $scope.map = mapGen('map'); 
    } 
    function init(App) { 
     App.controller('AppCtrl', ['$scope', AppController]); 
     return AppController; 
    } 
    return { start: init }; 
}); 

나는 각 응용 프로그램을 부트 스트랩 전에 Esri는/도장 비트를 사용하여 내 모든 각도 비트를 구축 부트 스트랩 모듈을 사용합니다.

define([ 
    'angular', 
    'controllers/AppController', 
    'widgets/search/SearchBootstrap' 
], function(angular, AppController, SearchBootstrap) { 
    function init() { 
     var App = angular.module('app', ['ui.bootstrap']); 
     AppController.start(App); 
     SearchBootstrap.start(App); 
     // need to bootstrap angular since we wait for dojo/DOM to load 
     angular.bootstrap(document.body, ['app']); 
     return App; 
    } 
    return { start: init }; 
}); 

희망이 조금 있습니다.