2013-07-09 23 views
9

मैं एक कोणीय अनुप्रयोग के अंदर ArcGIS JavaScript API का उपयोग करने की कोशिश कर रहा हूं। जैसा कि मैंने देखा, यह डोजो का उपयोग करता है। तो, मैं इस तरह कोणीय निर्देश से 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 सही है

मेरा प्रश्न, एंगुलर ऐप के अंदर आर्कजीआईएस कार्यक्षमता को इंजेक्ट करने के लिए सही तरीके से कैसे है?

उत्तर

12

मुझे लगता है कि इसके लिए एक बहुत ही 'कोणीय जेएस' शैली दृष्टिकोण निम्न जैसा होगा। (यहां http://jsfiddle.net/technicolorenvy/2Ke62/4/)

मुझे angular-ui-router का उपयोग करना पसंद है, लेकिन यह दृष्टिकोण w/कोणीय के $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; 
       } 
      } 
     }); 
    }); 

आप ऊपर देख सकते हैं, हम एक map राज्य एक resolve प्रोप है कि है। फिर आप एक ऑब्जेक्ट बना सकते हैं जो आपके आर्कजीआईएस/डोजो निर्भरताओं का प्रतिनिधित्व करता है और इसे अपने wish.loadDependencies (नीचे देखें) पर भेजता है।

q इस्तेमाल करते हुए हम एक वादा है कि एक बार सभी निर्भरता अपने 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; 
      } 
     }; 
    }); 
उसके बाद

, के माध्यम से लोड किए गए हैं का समाधान हो जाता है वापस आ जाएगी, तो आप कर सकते हैं सभी ArcGIS/डोजो FNS सीधे कॉल (आप के रूप में आमतौर पर), deps ऑब्जेक्ट में उपयोग की जाने वाली कुंजियों द्वारा ऐप कॉन्फ़िगरेशन के दौरान बनाया गया था, क्योंकि अब वे wish.get() द्वारा लौटे ऑब्जेक्ट से जुड़े हुए हैं।

क्या इस प्रकार उदाहरण यहाँ (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 लोड करने के लिए एक विभाजित दूसरा लेता है, जिसके कारण कोणीय अनुवाद को {{'कुछ' | अनुवाद}} ​​के रूप में प्रस्तुत किया जाता है जब तक 'आवश्यकता' लोड करने के लिए init.js लोड नहीं हो जाता है। क्या आप इच्छा सेवा के अंदर आवश्यकता निर्भरता को हटाने के तरीके से जानते हैं? – laitha0

+0

मैं इसे अपने यूआई में प्रीलोडर या 'डेटा लोडेड' झंडे के माध्यम से संभाल दूंगा। यहां समस्या का एक सुंदर सभ्य स्पष्टीकरण और संभावित समाधान http://www.code-hound.com/add-a-preloader-to-your-website-using-angularjs/ – technicolorenvy

+0

धन्यवाद, मैं इसे आज़माउंगा। – laitha0

7

ऐसा लगता है कि आप निर्देशक तत्व के अंदर अपना नक्शा बनाने की कोशिश कर रहे हैं। यह एक वैध उपयोग है, लेकिन मैं यह सुनिश्चित कर दूंगा कि आप अपने मॉड्यूल को लोड करने के लिए दोजो के एएमडी लोडर का उपयोग करें और फिर सभी डोजो भलाई के बाद bootstrap अपने कोणीय ऐप तैयार करें।

मैंने हाल ही में अंगुलर/एस्सी देव पर एक लेख लिख दिया है, और एक नमूना परियोजना के लिए स्रोत कोड 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 }; 
}); 

मैं एक बूटस्ट्रैप मॉड्यूल का उपयोग कोणीय आवेदन bootstrapping से पहले अपने सभी कोणीय 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 }; 
}); 

उम्मीद है कि थोड़ा सा मदद करता है।

संबंधित मुद्दे