自定义小部件中的自定义小部件
无可否认,我仍然是Dojo的新手,而且我一直在使用Javascript,所以在这里找借口和草率的代码或语言。自定义小部件中的自定义小部件
我正在使用Dojo 1.7.1和Spring Roo 1.2.1RELEASE。我通过CDM从Google加载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>
这里是JS的thumbailer:
// 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 /文本加载的模板。我试过做“./path/Template.html”和“/module/path/Template.html”,但第一个似乎尝试通过CDN(上面链接的Google API网站)解析URL,后者似乎想要一个完全合格的路径。我快门放入一条完整的道路,因为它似乎是一个肮脏的方式来做到这一点。我也尝试添加到dojoConfig路径为这样的:
paths: [
{ "message" : "${message_dojo_module_base_url}" }
]
但是这似乎并没有在所有帮助,导致Chrome的JS控制台一些非常讨厌的错误。
如果我正确阅读here,不要dojo/text使用模块吗?
很难告诉确切的问题是什么,但一对夫妇的事情,我跳出:如果您使用的1.7(dojoConfig
的djConfig
对象应该被命名为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装载机风格。 AMD风格的产品占99%。所有你需要做的是
- 删除dojo.provide和dojo.requires
- 更新
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 });
我怀疑与AMD的风格传统风格ArtThumbnailWidget
组合是WH在迷惑ArtTableWidget
。
djConfig是旧名称。 dojoConfig是新名称。请参阅http://dojotoolkit.org/documentation/tutorials/1.7/dojo_config/。 –
我在输入答案时查看了确切的页面。自从代码片段正确后,必须在编写代码时切换。更新我的答案以保持一致。 – BuffaloBuffalo
感谢BuffaloBuffalo。我接受了你的建议,改变了我的习惯组件,现在至少转移到了另一个问题。我得到了与上面类似的错误,但是现在在CDN的dojo/parser中。另外,当我使用dojo /文本时,它似乎无法找到我的本地模板文件!插件...它试图解析“./”到CDN网址。我尝试着在前面的模块名称上,但它似乎根本不使用模块。尽管如此,我仍然在尝试一些事情,并会回报。 – CodeChimp
所以,是的,这里有很多东西可能是错误的。你能得到一个更小的例子来工作吗?
- 这绝对值得一试的浏览器开发者工具的“网络”标签,看什么它试图加载。这通常有助于模块分辨率。同步运行(我认为你是),而不是异步模式也有助于诊断。
- 你应该注册img/ArtThumbnailWidget在你的modulePaths而不是img.ArtThumbnailWidget?
- 长期来看,您可能希望注册软件包而不是逐个模块...
- 您应该能够参考dojo/text!./ templates/ArtThumbnailWidget.html而不是dojo/text!img /ArtThumbnailWidget/templates/ArtThumbnailWidget.html在你的小部件中,但只有在加载小部件后才会变得相关。 (您的模块需求是相对于您的模块进行处理的。)
您是否解决了这个问题?请提供任何更新! – saravanakumar
对不起,我没有。我最终选择使用jQuery来完成这个项目,因为我永远无法在Dojo世界中弄清楚事情。 – CodeChimp
感谢您的回复:) – saravanakumar