<\/HEAD>
<\/P>
少し前に、AMDモジュールを活用する方法についての記事を書きました<\/A>。その際、ベストプラクティスや推奨されるモジュールの使い方の例を見て、いくつか質問が寄せられました。そこで今日はそれについてお手伝いしようと思います。<\/P><\/P>
私がしたのは、以前
ドキュメントからのサンプル<\/A>を機能追加して更新したもの<\/A>を使うことでした。<\/P><\/P>
このサンプルをAMDを使ってよりモジュール化されたアプリに分割できないか考えたかったのです。<\/P>
<\/P>
まずはコードを見てみましょう。HTMLは今は無視します。<\/P>
require([\n "esri\/Color", "esri\/dijit\/PopupTemplate", "esri\/layers\/FeatureLayer", "esri\/map", "esri\/renderers\/BlendRenderer",\n "esri\/symbols\/SimpleFillSymbol", "esri\/symbols\/SimpleLineSymbol", "dojo\/on", "dojo\/domReady!"\n], function (Color, PopupTemplate, FeatureLayer, Map, BlendRenderer, SimpleFillSymbol, SimpleLineSymbol, on){\n map = new Map("map", {\n basemap: "topo",\n center: [-118.40, 34.06],\n zoom: 15\n });\n \/\/_blendRendererのパラメータを設定\n var blendRendererParams = {\n \/\/_blendMode:"overlay" \/\/_デフォルトでは"source-over"を使用、異なるモードを表示したい場合はコメント解除\n \/\/_参照: <\/SPAN>https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/CanvasRenderingContext2D\/globalCompositeOperation<\/A>\n symbol: new SimpleFillSymbol().setOutline(new SimpleLineSymbol().setWidth(0)),\n fields: [\n {\n field: "OWNER_CY",\n label: "Owner Occupied",\n color: new Color([0, 0, 255])\n }, {\n field: "RENTER_CY",\n label: "Renter Occupied",\n color: new Color([255, 0, 0])\n }, {\n field: "VACANT_CY",\n label: "Vacant",\n color: new Color([0, 255, 0])\n }\n ],\n opacityStops: [\n {\n value: 0.1,\n opacity: 0\n }, \n {\n value: 1,\n opacity: 0.7\n }\n ],\n normalizationField: "TOTHU_CY"\n};\n//人口統計情報を表示するために使用するPopupTemplateを作成する\nvar template = new PopupTemplate({\n "title": "国勢調査ブロック別住宅状況",\n "fieldInfos": [\n { \n "fieldName": "OWNER_CY", \n "label": "所有者居住住宅数", \n "visible": true, \n "format": { \n "places": 0, \n "digitSeparator": true \n } \n }, { \n "fieldName": "RENTER_CY", \n "label": "賃借人居住住宅数", \n "visible": true, \n "format": { \n "places": 0, \n "digitSeparator": true \n } \n }, { \n "fieldName": "VACANT_CY", \n "label": "空き住宅数", \n displayable:true, \ n color : new Color ([0 , 255 , 0 ]) \ n } , \ n ] , \ n opacityStops : [ \ n { \ n value : 0.1 , \ n opacity : 0 \ n } , \ n { \ n value : 1 , \ n opacity : 0.7 \ n } ] , \ n normalizationField : "TOTHU_CY" \ n }); var layerUrl = " topic.subscribe('blend-select-update', hitch(this, 'updateBlendMode'))
);
},
updateBlendMode: function(mode) {
console.log('dojo/topicでブレンドモードを更新');
var layer = this.get('layer');
var renderer = this.get('renderer');
renderer.blendMode = mode;
layer.setRenderer(renderer);
layer.refresh();
}
});
});これはかなりシンプルなウィジェットです。セットアップにはpostCreateメソッドを使っています。
このビデオでdijitのライフサイクルについて話しています。このメソッドでレイヤーをセットアップし、オプションで渡されたレンダラーを割り当てています。シンプルなHTMLテンプレートは、データの説明があるサンプルのHTMLのコピーです。またdojo/topicも使っています。こちらで説明しています。ウィジェット間通信の異なる方法をいくつか示します。一つはdojo/topicを使う方法、もう一つはdojo/Eventedを使う方法です。
このモジュールにはupdateBlendModeメソッドもあり、単にdojo/topicのsubscribeを処理してblendModeを更新します。つまり、アプリケーション内のどのモジュールでもblendModeの更新をpublishできます。私の意見では、これは理想的なウィジェット通信方法です。なぜなら個々のウィジェットがお互いを意識する必要がないからです。
サンプルにはblendModeを更新できるセレクトメニューもありました。これも別のウィジェットに最適だと思います。このウィジェットのコードは次のようになるでしょう:
define([
'dojo/_base/declare',
'dojo/Evented',
'dojo/topic',
'dijit/_WidgetBase',
'dijit/_TemplatedMixin',
'dojo/text!./widget.html'
], function(
declare, Evented, topic,
_WidgetBase, _TemplatedMixin,
templateString
) {
return declare([_WidgetBase, _TemplatedMixin, Evented], {
templateString: templateString,
baseClass: 'blend-select',
onChange: function(e) {
var val = e.target.value;
if (this.cboxNode.checked) {
topic.publish('blend-select-update', val);
} else {
this.emit('blend-select-update', val);
}
}
});
})
このウィジェットはdojo/Eventedとdojo/topicを使っています。ウィジェット自体がdojo/_base/declareを使ってdojo/Eventedを拡張していることに気づくでしょう。これによりthis.emit()でイベントを発行できます。このウィジェットにはblendModes用のセレクトメニューと、新しいblendModeでイベントをemitするか、dojo/topic経由でpublishするかを設定するチェックボックスがあります。
テンプレートは次のようになっています:
<div>
<div>
<input type="checkbox" data-dojo-attach-point="cboxNode"> dojo/topic を使用
</div>
<select data-dojo-attach-event="change:onChange">
<option value="source-over">source-over</option>
<option value="source-in">source-in</option>
<option value="source-out">source-out</option>
<option value="source-atop">source-atop</option>
<option value="destination-over">destination-over</option>
<option value="destination-in">destination-in</option>
<option value="destination-out">destination-out</option>
<option value="destination-atop">destination-atop</option>
<option value="lighter">lighter</option>
<option value="copy">copy</option>
<option value="xor">xor</option>
<option value="overlay">overlay</option>
<option value="normal">complex</option>
<option value="multiply">multiply</option>
<option value="screen">screens</option>
<option value="darken">complex</option>
<option value="lighten">complex</option>
<option value="color-dodge">color-dodge</option>
<option value="color-burn">color-burn</option>
<option value="hard-light">complex</option>
  < option value= "soft-light "> ; soft-light & lt ; / option & gt ;
Dojoが読み込まれるとき。ドキュメントはこちらで確認できます。これにより、私の実際のindex.htmlファイルは非常にシンプルになります。<\/P><!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
<title>Modular App Demo</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.14/esri/css/esri.css"><\/SPAN>
<link rel="stylesheet" href="css/main.css">
<script src="dojoConfig.js"></script>
</head>
<body>
<div id="blend-selection-container"></div>
<div id="population-container"></div>
<div id="map"></div>
<script src="http://js.arcgis.com/3.14/"></script><\/SPAN>
</body>
</html><\/PRE>アプリケーションを初期化する他の方法についてはこちらをご覧ください。<\/P><\/P>一つずつ段階的に進めましょう<\/H2>モジュール化されたアプリケーション全体はこのgithubリポジトリで見つけることができます。これが、アプリケーションをモジュールに分割する方法や、自分の開発でモジュール性について考え始める方法の参考になれば幸いです。私は編集、検索、ジオコーディング、さらには動作の追加など、アプリケーションの機能をそれぞれ独自のウィジェットに分けるのが好きです。<\/P><\/P>過去に私が取り組んだモジュール性の他のサンプルは、完全に設定可能なstarter-kitや、最新の実験であるyeoman generator、およびsample appで見ることができます。非常にモジュール化されている別のアプリとしてはcmv appなどがあります。<\/P><\/P>繰り返しますが、これは単に私の意見ですが、アプリをより小さなモジュールに分割することで、時間が経ってもメンテナンスしやすく、新しい機能も簡単に追加できるようになると考えています。<\/P><\/P>さらに多くのgeodevのヒントやコツについては、私のブログをご覧ください。<\/P><\/BODY><\/HTML>