不可否认,我仍然是Dojo的新手,而且我一直对Javascript很弱,所以这里有借口和邋code的代码或语言。
我正在使用Spring Roo 1.2.1RELEASE的Dojo 1.7.1。我正在从Google通过CDM加载Dojo。
我前段时间创建了一个自定义图像缩略图查看器,可以在我的网站上使用,我在Spring Roo的load-scripts.tagx中添加了一个模块给我的djConfig,它在每个页面加载时运行。缩略图Widget不遵循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>
以下是thumbailer的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
});
现在我正在尝试添加另一个自定义组件,即上述缩略图的表格。新代码需要引用这个旧的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”,附加的Object看起来是我的ArtTableWidget。我注意到在挖掘这个对象时,“deps”成员看起来是顶部define()中定义的所有依赖项的数组,其中包含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 我使用BuffaloBuffalo的回复中的信息更新了所有模块,除了dojoConfig中的“路径”,我使用了以下内容:
<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控制台出现一些非常糟糕的错误。
如果我正确阅读here,那么dojo / text不会使用这些模块吗?
答案 0 :(得分:1)
很难说出确切的问题是什么,但有几件事情突然发生在我身上:
如果使用1.7,djConfig
对象应命名为dojoConfig
(dojoConfig仍可正常工作,但也可以更新它。)
modulePaths
属性应更新为path
。如果img.ArtThumbnailWidget
和img.ArtTableWidget
位于公共目录中,您可以使用以下内容:
var dojoConfig = {
parseOnLoad: false,
isDebug: false,
locale: '${fn:toLowerCase(userLocale)}',
paths: {
"message": "${message_dojo_url}",
"img": "${art_module_url}"
}
};
第二件事是img.ArtThumbnailWidget中的混合遗留/ amd加载器样式。你有99%的AMD风格。您需要做的就是
require([],function(){..});
更新为define([],function(){..});
更新声明中的引用以使用局部变量而不是全局变量:
//ArtThumbnailWidget
define('img/ArtThumbnailWidget', [
"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) {
return declare("img.ArtThumbnailWidget", [_WidgetBase, _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 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
});
我怀疑ArtThumbnailWidget
中遗留风格与amd风格的结合让人感到困惑ArtTableWidget
。
答案 1 :(得分:0)
所以,是的,这里有很多可能有问题的东西。你能得到一个更小的例子吗?