导入ArcGIS Javascript API资源并加载dojo时出现问题

时间:2016-07-13 18:56:38

标签: javascript angularjs jsp dojo arcgis-js-api

我正在使用ArcGIS Javascript API将一些功能(搜索小部件)添加到使用AngularJS和JSP的现有Web应用程序。我在解析esri / dijit / Search包的路径名时遇到问题,因为它在本地服务器而不是在线API上尝试路径名并产生404错误。

编辑我现在看到,如果我引用在线ArcGIS Javascript API,我有一个接收404错误的本地文件。当然,不引用它会导致esri / dijit / Search文件出现问题。我现在专注于配置这个,以便我可以解决这两个路径名。更新后的代码位于编辑部分的下方。

我有一个带有require函数的app.js:

'use strict';

var mapApp=angular.module('org.ours.app.map', ['ngRoute','org.ours.app.map.controllers']);

mapApp.config(['$routeProvider', function($routeProvider,StudentController) {
    $routeProvider.when('/', { controller: 'MapController'});
    $routeProvider.otherwise({redirectTo: '/'});
}]);

require([
    "esri/map",
    "dojo/domReady!",
    "esri/toolbars/navigation",
    "esri/toolbars/draw",
    "esri/layers/ArcGISDynamicMapServiceLayer",
    "esri/tasks/IdentifyParameters",
    "esri/tasks/IdentifyResult",
    "esri/tasks/IdentifyTask",
    "esri/layers/GraphicsLayer",
    "esri/dijit/InfoWindow",
    "esri/dijit/Search",
    "esri/layers/FeatureLayer",
    "esri/InfoTemplate"
  ], function () {
    var lScope=angular.element(document.getElementById('mapDiv')).scope();
    lScope.onReady.apply(lScope,arguments);
});

“搜索”窗口小部件的控制器(改编自在线ArcGIS示例):

'use strict';

mapAppControllers.controller('SearchController', function($rootScope, $scope) {
    $scope.$parent.searchScope=$scope;
    var me=$scope;
    var ALL;
    angular.extend($scope,{
        init:function(Map, Search, FeatureLayer, InfoTemplate, pMap){
            me.map=pMap;
            me.search = new Search({
               enableButtonMode: true, //this enables the search widget to display as a single button
               enableLabel: false,
               enableInfoWindow: true,
               showInfoWindowOnSelect: false,
               map: map
            }, "search");

            me.sources = search.get("sources");

            sources.push({
               featureLayer: new FeatureLayer("https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/US_Senators/FeatureServer/0"),
               searchFields: ["Name"],
               displayField: "Name",
               exactMatch: false,
               name: "Senator",
               outFields: ["*"],
               placeholder: "Senator name",
               maxResults: 6,
               maxSuggestions: 6,

               //Create an InfoTemplate

               infoTemplate: new InfoTemplate("Senator information", "Name: ${Name}</br>State: ${State}</br>Party Affiliation: ${Party}</br>Phone No: ${Phone_Number}<br><a href=${Web_Page} target=_blank ;'>Website</a>"),

               enableSuggestions: true,
               minCharacters: 0
            });

            //Set the sources above to the search widget
            search.set("sources", sources);

            search.startup();

        }
    })
});

然后我有一个index.jsp,其中包含一些地图元素,包括我试图添加的搜索小部件(在底部)。我在这里引用了在线ArcGIS Javascript API,但我不确定它是否在正确的位置。我也想知道是否有另一个包重新路由/ esri / dijit / Search文件。

此版本创建了404错误,该错误在http://ouserver/esri/dijit/Search中查找文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><!doctype html>
<html ng-app="org.ours.app.map" class="map-viewport">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="js/arcgis/esri/css/esri.css">
  <link rel="stylesheet" href="css/bootstrap/bootstrap.css">
  <link rel="stylesheet" href="css/bootstrap/bootstrap-theme.css">

  <link rel="stylesheet" href="css/map.css">

  <script src="js/arcgis/dojo/dojo.js" data-dojo-config="async: true"></script>
  <script src="js/angularjs/angular.min.js"></script>
  <script src="js/angularjs/i18n/angular-locale_fr-fr.js"></script>
  <script src="js/angularjs/angular-animate.min.js"></script>
  <script src="js/angularjs/angular-route.min.js"></script>
  <script src="js/bootstrap/ui-bootstrap-tpls-1.1.2.min.js"></script>


  <script src="js/utils/ColorsUtil.js"></script>

  <script src="js/controllers.js"></script>

  <script src="js/controllers/Attributes.js"></script>
  <script src="js/controllers/Results.js"></script>
  <script src="js/controllers/Identify.js"></script>
  <script src="js/controllers/Toolbar.js"></script>
  <script src="js/controllers/MapService.js"></script>
  <script src="js/controllers/Map.js"></script>
  <script src="js/controllers/Body.js"></script>
  <script src="js/controllers/Search.js"></script>

  <script src="js/app.js"></script>

</head>
<body ng-controller="BodyController" class="map-body">

<div style="display: none" ng-controller="IdentifyController"></div>



<div id="mapDiv" ng-controller="MapController">
  <script type="text/ng-template" id="infoWindowTemplate.html">
    <div style="max-height: 300px;overflow-y: auto;overflow-x: hidden">
      <table cellpadding="2">
        <tbody>
        <tr ng-repeat="attribute in resultsScope.popover.attributes" ng-class="$index%2==1?'map-attributes-even':''" >
          <td style="font-weight: bold" >{{attribute.label}}</td>
          <td style="padding-left: 5px" uib-tooltip="{{attribute.value}}">{{attribute.value}}</td>
        </tr>
        </tbody>
      </table>
    </div>
  </script>
  <div id="popoverPosition"
       popover-title="{{resultsScope.popover.title}}"
       uib-popover-template="resultsScope.popover.templateUrl"
       popover-is-open="resultsScope.popover.isOpen"
  ></div>
</div>

<div class="map-toolbar"  ng-controller="ToolbarController" id="toolbar">
  <div class="btn-group">
    <label class="btn btn-primary" ng-click="onMapActionClick('prev')" ng-disabled="navModel.prev" uib-tooltip="Vue précédente" tooltip-placement="bottom"><i class="glyphicon glyphicon-circle-arrow-left"></i></label>
    <label class="btn btn-primary" ng-model="mapTool" uib-btn-radio="'pan'" uib-tooltip="Déplacer" tooltip-placement="bottom"><i class="glyphicon glyphicon-move"></i></label>
    <label class="btn btn-primary" ng-click="onMapActionClick('next')" ng-disabled="navModel.next" uib-tooltip="Vue suivante" tooltip-placement="bottom"><i class="glyphicon glyphicon-circle-arrow-right"></i></label>
  </div>
  <div class="btn-group">
    <label class="btn btn-primary" ng-model="mapTool" uib-btn-radio="'zoomout'" uib-tooltip="Dézoomer" tooltip-placement="bottom"><i class="glyphicon glyphicon-zoom-out"></i></label>
    <label class="btn btn-primary" ng-click="onMapActionClick('full')" uib-tooltip="Vue globale" tooltip-placement="bottom"><i class="glyphicon glyphicon-fullscreen"></i></label>
    <label class="btn btn-primary" ng-model="mapTool" uib-btn-radio="'zoomin'" uib-tooltip="Zoomer" tooltip-placement="bottom"><i class="glyphicon glyphicon-zoom-in"></i></label>
  </div>
  <div class="btn-group">
    <label class="btn btn-primary" ng-model="mapTool" uib-btn-radio="'identify'" uib-tooltip="Identifier" tooltip-placement="bottom"><i class="glyphicon glyphicon-info-sign"></i></label>
  </div>

  <div class="btn-group" style="display: inline-block;width:400px" ng-controller="MapServiceController">
    <script type="text/ng-template" id="serviceLyerTemplate.html">
      <a>
        <span ng-bind-html="match.label | uibTypeaheadHighlight:query | BoldLayersOptions:match"></span>
      </a>
    </script>
    <div style="display: inline-block;" >
      <input type="text" ng-model="serviceSelected" placeholder="Selectionner un service" uib-typeahead="service as service.name for service in services | filter:{name:$viewValue}"
             typeahead-template-url="serviceLyerTemplate.html" class="form-control" typeahead-show-hint="true" typeahead-min-length="0" style="display: inline-block;"
             typeahead-on-select="onServiceSelect($model)" typeahead-select-on-blur="true">
    </div>
    <div style="display: inline-block;width:50%">
      <input type="text" ng-model="layerSelected" placeholder="Selectionner une couche" uib-typeahead="layer as layer.name for layer in layers | filter:{name:$viewValue}"
             typeahead-template-url="serviceLyerTemplate.html" class="form-control" typeahead-show-hint="true" typeahead-min-length="0" style="display: inline-block;"
             typeahead-on-select="onLayerSelect($model)" typeahead-select-on-blur="true"
      >
    </div>
  </div>

</div>

<div class="map-messagebar">
  <uib-alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)" style="width: 600px">{{alert.msg}}</uib-alert>
</div>

<label class="btn btn-success map-identify" ng-model="resultsScope.visible" uib-btn-checkbox ng-click="attributesScope.visible=$event.ctrlKey?resultsScope.visible:attributesScope.visible"><i class="glyphicon glyphicon-info-sign"></i></label>
<label class="btn btn-success map-show-attributes" ng-model="attributesScope.visible" uib-btn-checkbox ng-click="resultsScope.visible=$event.ctrlKey?attributesScope.visible:resultsScope.visible"><i class="glyphicon glyphicon-list-alt"></i></label>
<button class="btn btn-success map-reset" ng-click="reset()"><i class="glyphicon glyphicon-remove-sign"></i></button>



<div class="panel panel-primary map-results animate-hide" id="resultsDiv" ng-controller="ResultsController" ng-show="visible">
  <div class="panel-heading"><i class="glyphicon glyphicon-info-sign"></i> Résultats<i class="pull-right glyphicon glyphicon-chevron-left" ng-click="visible=!visible"></i></div>
  <div class="panel-body map-results-body" >
    <uib-accordion close-others="oneAtATime" style="width: 100%;height: 100%">
      <uib-accordion-group ng-repeat="layer in layers" is-open="layer.isFirstOpen" class="panel panel-success">
        <uib-accordion-heading><i class="glyphicon glyphicon-play" ng-style="layer.style"></i> {{layer.name}}</uib-accordion-heading>
        <label class="btn btn-link btn-default map-result" ng-model="result.visible" ng-click="show(result)" ng-repeat="result in layer.results" uib-btn-checkbox>
          {{result.displayValue}}
          <i class="pull-right glyphicon glyphicon-fullscreen" ng-click="zoom(result,$event)"></i>
          <i class="pull-right glyphicon glyphicon-list-alt" ng-click="attributesScope.visible=true;attributesScope.show(result,$event)" style="margin-right:5px"></i>
        </label>
      </uib-accordion-group>
    </uib-accordion>
  </div>
</div>

<div class="panel panel-primary map-attributes" id="attributesDiv" ng-controller="AttributesController" ng-show="visible">
  <div class="panel-heading"><i class="glyphicon glyphicon-list-alt"></i> Attributs<i class="pull-right glyphicon glyphicon-chevron-right" ng-click="visible=!visible"></i></div>
  <div class="panel-body map-attributes-body">
    <table cellpadding="2">
      <tbody>
      <tr ng-repeat="attribute in attributes" ng-class="$index%2==1?'map-attributes-even':''" ><td style="font-weight: bold">{{attribute.label}}</td><td style="padding-left: 5px">{{attribute.value}}</td></tr>
      </tbody>
    </table>
  </div>
</div>

<script src="https://js.arcgis.com/3.17/"></script>

<div ng-controller="SearchController" id="search">
  <h1> This is a test </h1>
</div>

</body>
</html>

包中还有许多其他文件。我对此很陌生,所以我愿意接受关于在哪里寻找的建议。这是文件结构:

enter image description here

编辑将ArcGIS API参考移动到index.jsp的顶部时,我现在遇到解决dojo_fr.js问题(在本地服务器上)。如何配置它以便两者都得到解决?

此版本在https://js.arcgis.com/3.17/dojo/nls/dojo_fr.js中查找文件时会产生404错误:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><!doctype html>
<html ng-app="pf.pde.app.map" class="map-viewport">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="js/arcgis/esri/css/esri.css">
  <link rel="stylesheet" href="css/bootstrap/bootstrap.css">
  <link rel="stylesheet" href="css/bootstrap/bootstrap-theme.css">

  <link rel="stylesheet" href="css/map.css">

  <script src="https://js.arcgis.com/3.17/"></script>

  <script src="js/arcgis/dojo/dojo.js" data-dojo-config="async: true"></script>
  <script src="js/angularjs/angular.min.js"></script>
  <script src="js/angularjs/i18n/angular-locale_fr-fr.js"></script>
  <script src="js/angularjs/angular-animate.min.js"></script>
  <script src="js/angularjs/angular-route.min.js"></script>
  <script src="js/bootstrap/ui-bootstrap-tpls-1.1.2.min.js"></script>


  <script src="js/utils/ColorsUtil.js"></script>

  <script src="js/controllers.js"></script>

  <script src="js/controllers/Attributes.js"></script>
  <script src="js/controllers/Results.js"></script>
  <script src="js/controllers/Identify.js"></script>
  <script src="js/controllers/Toolbar.js"></script>
  <script src="js/controllers/MapService.js"></script>
  <script src="js/controllers/Map.js"></script>
  <script src="js/controllers/Body.js"></script>
  <script src="js/controllers/Search.js"></script>

  <script src="js/app.js"></script>

</head>
<body ng-controller="BodyController" class="map-body">

<div style="display: none" ng-controller="IdentifyController"></div>



<div id="mapDiv" ng-controller="MapController">
  <script type="text/ng-template" id="infoWindowTemplate.html">
    <div style="max-height: 300px;overflow-y: auto;overflow-x: hidden">
      <table cellpadding="2">
        <tbody>
        <tr ng-repeat="attribute in resultsScope.popover.attributes" ng-class="$index%2==1?'map-attributes-even':''" >
          <td style="font-weight: bold" >{{attribute.label}}</td>
          <td style="padding-left: 5px" uib-tooltip="{{attribute.value}}">{{attribute.value}}</td>
        </tr>
        </tbody>
      </table>
    </div>
  </script>
  <div id="popoverPosition"
       popover-title="{{resultsScope.popover.title}}"
       uib-popover-template="resultsScope.popover.templateUrl"
       popover-is-open="resultsScope.popover.isOpen"
  ></div>
</div>

<div class="map-toolbar"  ng-controller="ToolbarController" id="toolbar">
  <div class="btn-group">
    <label class="btn btn-primary" ng-click="onMapActionClick('prev')" ng-disabled="navModel.prev" uib-tooltip="Vue précédente" tooltip-placement="bottom"><i class="glyphicon glyphicon-circle-arrow-left"></i></label>
    <label class="btn btn-primary" ng-model="mapTool" uib-btn-radio="'pan'" uib-tooltip="Déplacer" tooltip-placement="bottom"><i class="glyphicon glyphicon-move"></i></label>
    <label class="btn btn-primary" ng-click="onMapActionClick('next')" ng-disabled="navModel.next" uib-tooltip="Vue suivante" tooltip-placement="bottom"><i class="glyphicon glyphicon-circle-arrow-right"></i></label>
  </div>
  <div class="btn-group">
    <label class="btn btn-primary" ng-model="mapTool" uib-btn-radio="'zoomout'" uib-tooltip="Dézoomer" tooltip-placement="bottom"><i class="glyphicon glyphicon-zoom-out"></i></label>
    <label class="btn btn-primary" ng-click="onMapActionClick('full')" uib-tooltip="Vue globale" tooltip-placement="bottom"><i class="glyphicon glyphicon-fullscreen"></i></label>
    <label class="btn btn-primary" ng-model="mapTool" uib-btn-radio="'zoomin'" uib-tooltip="Zoomer" tooltip-placement="bottom"><i class="glyphicon glyphicon-zoom-in"></i></label>
  </div>
  <div class="btn-group">
    <label class="btn btn-primary" ng-model="mapTool" uib-btn-radio="'identify'" uib-tooltip="Identifier" tooltip-placement="bottom"><i class="glyphicon glyphicon-info-sign"></i></label>
  </div>

  <div class="btn-group" style="display: inline-block;width:400px" ng-controller="MapServiceController">
    <script type="text/ng-template" id="serviceLyerTemplate.html">
      <a>
        <span ng-bind-html="match.label | uibTypeaheadHighlight:query | BoldLayersOptions:match"></span>
      </a>
    </script>
    <div style="display: inline-block;" >
      <input type="text" ng-model="serviceSelected" placeholder="Selectionner un service" uib-typeahead="service as service.name for service in services | filter:{name:$viewValue}"
             typeahead-template-url="serviceLyerTemplate.html" class="form-control" typeahead-show-hint="true" typeahead-min-length="0" style="display: inline-block;"
             typeahead-on-select="onServiceSelect($model)" typeahead-select-on-blur="true">
    </div>
    <div style="display: inline-block;width:50%">
      <input type="text" ng-model="layerSelected" placeholder="Selectionner une couche" uib-typeahead="layer as layer.name for layer in layers | filter:{name:$viewValue}"
             typeahead-template-url="serviceLyerTemplate.html" class="form-control" typeahead-show-hint="true" typeahead-min-length="0" style="display: inline-block;"
             typeahead-on-select="onLayerSelect($model)" typeahead-select-on-blur="true"
      >
    </div>
  </div>

</div>

<div class="map-messagebar">
  <uib-alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)" style="width: 600px">{{alert.msg}}</uib-alert>
</div>

<label class="btn btn-success map-identify" ng-model="resultsScope.visible" uib-btn-checkbox ng-click="attributesScope.visible=$event.ctrlKey?resultsScope.visible:attributesScope.visible"><i class="glyphicon glyphicon-info-sign"></i></label>
<label class="btn btn-success map-show-attributes" ng-model="attributesScope.visible" uib-btn-checkbox ng-click="resultsScope.visible=$event.ctrlKey?attributesScope.visible:resultsScope.visible"><i class="glyphicon glyphicon-list-alt"></i></label>
<button class="btn btn-success map-reset" ng-click="reset()"><i class="glyphicon glyphicon-remove-sign"></i></button>



<div class="panel panel-primary map-results animate-hide" id="resultsDiv" ng-controller="ResultsController" ng-show="visible">
  <div class="panel-heading"><i class="glyphicon glyphicon-info-sign"></i> Résultats<i class="pull-right glyphicon glyphicon-chevron-left" ng-click="visible=!visible"></i></div>
  <div class="panel-body map-results-body" >
    <uib-accordion close-others="oneAtATime" style="width: 100%;height: 100%">
      <uib-accordion-group ng-repeat="layer in layers" is-open="layer.isFirstOpen" class="panel panel-success">
        <uib-accordion-heading><i class="glyphicon glyphicon-play" ng-style="layer.style"></i> {{layer.name}}</uib-accordion-heading>
        <label class="btn btn-link btn-default map-result" ng-model="result.visible" ng-click="show(result)" ng-repeat="result in layer.results" uib-btn-checkbox>
          {{result.displayValue}}
          <i class="pull-right glyphicon glyphicon-fullscreen" ng-click="zoom(result,$event)"></i>
          <i class="pull-right glyphicon glyphicon-list-alt" ng-click="attributesScope.visible=true;attributesScope.show(result,$event)" style="margin-right:5px"></i>
        </label>
      </uib-accordion-group>
    </uib-accordion>
  </div>
</div>

<div class="panel panel-primary map-attributes" id="attributesDiv" ng-controller="AttributesController" ng-show="visible">
  <div class="panel-heading"><i class="glyphicon glyphicon-list-alt"></i> Attributs<i class="pull-right glyphicon glyphicon-chevron-right" ng-click="visible=!visible"></i></div>
  <div class="panel-body map-attributes-body">
    <table cellpadding="2">
      <tbody>
      <tr ng-repeat="attribute in attributes" ng-class="$index%2==1?'map-attributes-even':''" ><td style="font-weight: bold">{{attribute.label}}</td><td style="padding-left: 5px">{{attribute.value}}</td></tr>
      </tbody>
    </table>
  </div>
</div>



<div ng-controller="SearchController" id="search">
  <h1> This is a test </h1>
</div>

</body>
</html>

更新我试图做dojoConfig,但我仍然没有得到它(请参阅目前的情况如下)。还有其他一些东西阻止了页面加载。当这些东西被消除后,页面加载,其余的工作:

-ArcGIS API在线参考(dojo_fr.js上404错误) -requiring esri / Search / dijit(如果我没有按照以下方式引用ArcGIS API,则会在Search.js上出现404错误)

  <script src="https://js.arcgis.com/3.17/"></script>

  <!-- First dojoConfig -->
     <script type="text/javascript">
     var dojoConfig = {
        packages: [
            {
                location: '/js/arcgis',
                name: 'arcgis'
            }
        ]
     };
  </script>

  <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>

  <script src="js/arcgis/dojo/dojo.js" data-dojo-config="async: true"></script>

1 个答案:

答案 0 :(得分:0)

我认为您需要的是Configuring Dojo with dojoConfig,因为我在您的代码中看不到它。基本上,您需要在包含dojoConfig之前创建dojo var,例如:

<!-- If including dojo from googleapis -->
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>

<!-- And later do this -->
<script type="text/javascript">
    require([
        'myApp/myComponent',
        'dojo/dom',
        'dojo/dom-construct'
        ], function(myComponent, dom, domConstruct) {
            //do something
    });
</script>

加载myApp/myComponent将失败,因为加载程序将使用此URL

http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/myApp/myComponent.js

但是,如果在加入dojo之前,我们会发起dojoConfig

<!-- First dojoConfig -->
<script type="text/javascript">
     var dojoConfig = {
        packages: [
            {
                location: '/js/myApp',
                name: 'myApp'
            }
        ]
     };
</script>

 <!-- Then load dojo -->
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>

然后加载器将尝试从我的本地服务器获取myApp/myComponent

请注意,这是您如何使用dojoContig

的说明性示例