確かに、私はまだ Dojo の初心者であり、常に Javascript に弱いので、言い訳をしてずさんなコードまたは言語を使用します。
Spring Roo 1.2.1RELEASE で Dojo 1.7.1 を使用しています。Googleから CDM を介して Dojo をロードしています。
少し前に、自分のサイトで使用するカスタムの画像サムネイル ビューアを作成しました。これは、Spring Roo の load-scripts.tagx の djConfig にモジュールを追加することでインクルードし、ページが読み込まれるたびに実行されます。サムネイル ウィジェットは AMD のパターンに従っていません。
djConfig は次のとおりです。
<script type="text/javascript">
var djConfig = {
parseOnLoad: false,
isDebug: false,
locale: '${fn:toLowerCase(userLocale)}',
modulePaths: {
"message": "${message_dojo_url}",
"img.ArtThumbnailWidget": "${artThumbnailWidget_dojo_url}",
"img.ArtTableWidget": "${artTableWidget_dojo_url}",
},
};
</script>
これがサムネイル用の JS です。
// img.ArtThumbnailWidget
dojo.provide("img.ArtThumbnailWidget");
dojo.require("dojo._base.declare");
dojo.require("dojo.parser");
dojo.require("dojo.ready");
dojo.require("dijit._WidgetBase");
dojo.require("dijit._TemplatedMixin");
dojo.require("dojox.image.LightboxNano");
// Create the widget
require([
"dojo/_base/declare",
"dojo/parser",
"dojo/ready",
"dijit/_WidgetBase",
"dijit/_TemplatedMixin",
"dojo/dom",
"dojo/dom-construct",
"dojo/on",
"dojo/text!img/ArtThumbnailWidget/templates/ArtThumbnailWidget.html",
"dojox/image/LightboxNano",
"dojo/domReady!"
], function(declare, parser, ready, _WidgetBase, _TemplatedMixin, dom, domConstruct, on, template) {
dojo.declare("img.ArtThumbnailWidget",[dijit._WidgetBase, dijit._TemplatedMixin], {
/* Our properties will go here */
// Art JSON object, default is null
art: null,
// Viewer ID (the username of the person looking at this image), which will default to null
viewerId: null,
// maxThumbnailSize is how large of an image to return for the thumbnail. The back-end will resize the thumbnail accordingly
maxThumbnailSize: 100,
// maxImageSize is how large of an image to return for the LightboxNano. The back-end will resize the image accordingly
maxImageSize: 500,
// Our template - important!
templateString: template,
// A class to be applied to the root node in our template
baseClass: "artThumbnailWidget",
// Specifies there are widgets in the template itself that need to be rendered as well
widgetsInTemplate: true,
// Competition-related vars
competitionUrlBase: null,
competitionButtonIconUrl: null,
/* This is called once the DOM structure is ready, but before anything is shown */
postCreate: function() {
// Get a DOM node reference for the root of our widget
var domNode = this.domNode;
// Run any parent postCreate processes - can be done at any point
this.inherited(arguments);
if(this.art!=null && this.viewerId!=null && this.art.owner.name == this.viewerId) { // If the view is the owner, add the toolbar
// TODO: We need to clean this up, make it "prettier", and make the URLs more generic
var toolbarNode = domConstruct.create("div", {}, this.containerNode);
if(this.competitionUrlBase!=null) {
var url = this.competitionUrlBase;
if(url.indexOf('?')<0) { // URL does not have a '?'
url = url+"?";
} else { // URL has a '?', so we need to tack on and additional '&'
url = url+"&";
}
url = url+"username="+this.art.owner.name+"&artPieceId="+this.art.id;
var compButtonNode = domConstruct.create("a",
{
href: url,
},toolbarNode);
var compButtonImg = domConstruct.create("img",
{
src: this.competitionButtonIconUrl,
width: this.maxThumbnailSize/4,
height: this.maxThumbnailSize/4,
},compButtonNode);
}
}
},
/* This private method is used to re-set the node values when something changes */
_resetNodeValues: function() {
if(this.art !=null) {
// Using our thumbnailNode attach point, set its src value
this.thumbnailNode.src = this.art.url+"?maxSize="+this.maxThumbnailSize;
this.thumbnailNode.alt = this.art.title;
this.thumbnailNode.width = this.maxThumbnailSize;
this.thumbnailNode.height = this.maxThumbnailSize;
// Now setup the link for the LightboxNano
var lightboxNano = new dojox.image.LightboxNano({
href: this.art.url+"?maxSize="+this.maxImageSize,
},this.thumbnailNode);
}
},
/* This is called anytime the "art" attribute is set. Consider is a "setter" method */
_setArtAttr: function(av) {
if (av != null) {
// Save it on our widget instance - note that
// we're using _set, to support anyone using
// our widget's Watch functionality, to watch values change
this._set("art", av);
this._resetNodeValues();
} else {
// We could have a default here...would be an error, since we
// shouldn't be calling this without an art object
}
},
_setMaxThumbnailSizeAttr: function(ms) {
// Save it on our widget instance - note that
// we're using _set, to support anyone using
// our widget's Watch functionality, to watch values change
this._set("maxThumbnailSize", ms);
this._resetNodeValues();
},
_setMaxImageSizeAttr: function(ms) {
// Save it on our widget instance - note that
// we're using _set, to support anyone using
// our widget's Watch functionality, to watch values change
this._set("maxImageSize",ms);
this._resetNodeValues();
}
}); // End of the widget
});
今、別のカスタム コンポーネント、上記のサムネイルのテーブルを追加しようとしています。新しいコードはこの古いウィジェットを参照する必要がありますが、動作させることができないようです。
新しいテーブル ウィジェット (これまでのところ):
// in "img/ArtTableWidget"
define([
"dojo/_base/declare", "dojo/parser",
"dijit/_WidgetBase", "dijit/_TemplatedMixin",
"dojo/dom", "dojo/dom-construct","img/ArtThumbnailWidget",
"dojo/text!./ArtTableWidget/templates/ArtTableWidget.html"],
function(declare,parser,_WidgetBase,_TemplatedMixin, dom, domConstruct, ArtThumbnailWidget, template) {
return declare("img.ArtTableWidget",[dijit._WidgetBase,dijit._TemplatedMixin], {
// Default values for the ArtTable
// The base URL to use for downloading the photos
artUrlBase: null,
// The base URL used for submitting competitions and the button URL
newCompetitionUrlBase: null,
newCompetitionButtonIconUrl: null,
// Indicates what params on the URL are used to control page
// and size. These will be appended to the URL as needed.
pageNumberParameterName: "page",
pageSizeNumberParameterName: "size",
// Holds the page and size
page: 1,
size: 15,
totalPages: 0,
columns: 3,
// Holds the current list of "art"
artList: [],
// The userid currently viewing
viewerId: null,
// Our HTML template
templateString: template,
baseClass: "artTableWidget",
// Specifies there are widgets in the template itself that need to be rendered as well
widgetsInTemplate: true,
// Functions //
postCreate: function() {
this._load(this.page);
},
// Loads the given page
_load: function(pageToLoad) {
if(pageToLoad==null) {
pageToLoad=1;
}
// Generate the URL
genUrl = this.artUrlBase.indexOf("?")>=0 ? this.artUrlBase+"&page="+pageToLoad+"&size="+this.size : this.artUrlBase+"?page="+pageToLoad+"&size="+this.size;
// Make the call to the backend
dojo.xhrGet({
url: genUrl,
handleAs: "json",
tableWidget: this,
load: function(data,ioArgs) {
this.tableWidget.page = data.page;
this.tableWidget.totalPages = data.totalPages;
this.tableWidget.artList = data.data;
this.tableWidget._updateTable();
}
});
},
_updateTable: function() {
// Fix the buttons at the bottom
// Clear the artTable
domConstruct.empty(this.artTable);
// Loop through the art and build the rows
tableRow = tableRow = domConstruct.create("tr",{},this.artTable);
dojo.forEach(this.artList,function(art,index) {
if(index % columns == 0) {
tableRow = domConstruct.create("tr",{},this.artTable);
}
tableColumn = domConstruct.create("td",{style: { marginLeft: "auto", marginRight: "auto" }},tableRow);
var tnNode = new ArtThumbnailWidget({
art: art,
viewerId: this.viewerId,
competitionUrlBase: this.newCompetitionUrlBase,
competitionButtonIconUrl: this.newCompetitionButtonIconUrl,
});
tnNode.placeAt(tableColumn);
});
}
});
});
しかし、Chrome で新しいコンポーネントを実行すると、dojo.js.uncompressed.js 行 1716 で一般的なエラーが発生します。エラーのメッセージは「multipleDefine」であり、添付されたオブジェクトは ArtTableWidget のようです。このオブジェクトを掘り下げると、上部の define() で定義されたすべての依存関係の配列のように見える「deps」メンバーに img/ArtThumbnailWidget が含まれていることに気付きましたが、「pack」メンバーは未定義です。 . モジュールなどをロードしていないだけだと思います。
エラー (コピー/貼り付けが正しく表示されない場合は申し訳ありません) は次のとおりです。
dojo.js.uncompressed.js:1716
Error
arguments: undefined
get stack: function getter() { [native code] }
info: Object
cacheId: 0
cjs: Object
def: function (declare,parser,_WidgetBase,_TemplatedMixin, dom, domConstruct, ArtThumbnailWidget, template) {
deps: Array[8]
0: Object
1: Object
2: Object
3: Object
4: Object
5: Object
6: Object
cacheId: 0
def: 0
executed: 4
injected: 2
isAmd: false
isXd: null
mid: "img/ArtThumbnailWidget"
pack: undefined
pid: ""
result: Object
url: "/ArtSite/resources/img/ArtThumbnailWidget.js"
__proto__: Object
7: Object
length: 8
__proto__: Array[0]
executed: 0
injected: 2
isAmd: false
isXd: null
mid: "img/ArtTableWidget"
node: HTMLScriptElement
pack: undefined
pid: ""
require: function (a1, a2, a3){
result: Object
url: "/ArtSite/resources/img/ArtTableWidget.js"
__proto__: Object
message: "multipleDefine"
set stack: function setter() { [native code] }
src: "dojoLoader"
type: undefined
__proto__: ErrorPrototype
dojo.js.uncompressed.js:1719src: dojoLoader
dojo.js.uncompressed.js:1719info:
Object
dojo.js.uncompressed.js:1721.
ここで正しい軌道に戻るには、助けが必要です。
編集 1 dojoConfig の「パス」の代わりに以下を使用したことを除いて、BuffaloBuffalo の返信の情報を使用してすべてのモジュールを更新しました。
<script type="text/javascript">
var djConfig = {
parseOnLoad: false,
isDebug: false,
locale: '${fn:toLowerCase(userLocale)}',
packages: [
{ name: "message", location: "${message_dojo_module_base_url}" },
{ name: "img", location: "${img_dojo_module_base_url}" }
]
};
</script>
.js ファイルは見つかったようですが、dojo/textを使用してそこにロードされたテンプレートは見つかりませんでした。「./path/Template.html」と「/module/path/Template.html」をやってみましたが、前者はCDN(上記リンクのGoogle APIサイト)を介してURLを解決しようとするようで、後者は欲しいようです完全修飾パス。汚い方法のように思えるので、完全なパスを入れるためにシャッターを切ります。また、次のように dojoConfig へのパスを追加してみました。
paths: [
{ "message" : "${message_dojo_module_base_url}" }
]
しかし、それはまったく役に立たないようで、Chrome の JS コンソールで非常に厄介なエラーが発生しました。
ここで正しく読んでいる場合、dojo/text はモジュールを使用しませんか?