Dojo:如果无法获取初始数据,则灰显一个表单(或整个div)



我正在用Dojo编写一个简单的表单。这是我第一次"真正"使用Dojo来实际做一些事情。。。基本上:

1) 当显示小部件onShow时,它会尝试预加载表单应该具有的值2) 当用户提交时,使用相同的存储保存值

这里的"问题"是我正在尝试制作一个1000%的故障保护应用程序。例如,如果商店不工作(因此无法检索设置),我希望应用程序在3秒钟后重试——或者,当用户单击链接时。所以,我现在要做的是将所有的"获取"功能放入一个函数loadUp()中。如果出现问题,我将再次运行loadUp()(从promise中的错误回调),并且我还应该禁用该表单——比如将其变成灰色,现在允许输入)。

所以,问题:

1) 这是一种理智的做事方式吗?2) 你打算怎么办,把表格弄灰?

我意识到我在这里谈论的是工作区设置。因此,真正发生的是,"获取"将在整个过程的一开始就完成。然而,我会在几乎所有表单中重复使用这个…

这是代码:

var SettingsGeneral = declare('hotplate.bd.SettingsGeneral', [ ContentPane, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin ], { 
templateString: '' + 
'<div>' + 
'  <form data-dojo-type="dijit.form.Form" data-dojo-attach-point="form" method="POST"> ' + 
'    <input id="${id}_WorkspaceLongName" data-dojo-type="dijit/form/ValidationTextBox" name="longName" data-dojo-props="" />' + 
'    <input id="${id}_WorkspaceTag" data-dojo-type="dijit/form/ValidationTextBox" name="tag" data-dojo-props="" />' + 
'    <input class="formSubmit" type="submit" data-dojo-attach-point="button" data-dojo-type="hotplate.hotDojoWidgets.BusyButton" label="Create!" />' + 
'  </form>' + 
'</div>', 
onShow: function(){ 
this.inherited(arguments); 
// This returns a working store 
var workspaceSettings = stores('workspaceSettings', { workspaceIdCall: vars['hotDojoAppContainer']['workspaceId'] } ); 
function loadUp(){ 
// The server will return the settings for this particular workspace 
workspaceSettings.get('').then( 
function(res){ 
// All good... 
// Assign all of the received values to matching fields 
// TODO: Turn this into a function 
that.form._descendants.forEach(function( widget ) { 
console.log(widget); 
if( typeof( res.data[ widget.name ] ) !== 'undefined'){ 
widget.set('value', res.data[ widget.name] ); 
} 
}); 
}, 
function(err){ 
// Error: try this again in 3 seconds, hopefully it will work. It would actually be better having a 
// link to click for the user 
console.log("Something went wrong. The form needs to be disabled (turned grey?) and the connection should be retried"); 
setTimeout(loadUp, 3000); 
} 
); 
}; 
loadUp(); 
// Submit form 
this.form.onSubmit = ds.defaultSubmit(this.form, this.button, function(){ 
console.log("PRESSED!"); 
that.button.cancel(); 
console.log(workspaceSettings); 
// Use the same data store to save the settings... 
}); 
} 
}); 

以下是我所做的:

第1步:我在类中添加了一个mixin:_OverlayMixin,并设置onOverlayClick来重新显示小部件。我也会在调用show()后立即运行this.set( 'overlayed', true ); this.set( 'overlayClickable', false );,然后运行that.set( 'overlayed', false );(如果一切正常)或that.set('overlayClickable', true );(如果进展不顺利)。

步骤2:实际编写_OverlayMixin类

代码如下。_OverlayMixin类非常简单,是自包含的。它需要美化——现在它只是小部件上的一个灰色的东西。如果覆盖是可点击的,它将有一个类集——所以它可能有一个用于重试的图标。我喜欢我所做的,因为它很道场,而且读起来很简单。此外,如果出现问题,用户可以通过这种方式轻松地"重新启动"小部件。

这是代码。。。从我的简单小部件开始:

var SettingsGeneral = declare('hotplate.bd.SettingsGeneral', [ ContentPane, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _OverlayMixin ], { 
templateString: '' + 
'<div>' + 
'  <form data-dojo-type="dijit.form.Form" data-dojo-attach-point="form" method="POST"> ' + 
'    <input id="${id}_WorkspaceLongName" data-dojo-type="dijit/form/ValidationTextBox" name="longName" data-dojo-props="" />' + 
'    <input id="${id}_WorkspaceTag" data-dojo-type="dijit/form/ValidationTextBox" name="tag" data-dojo-props="" />' + 
'    <input class="formSubmit" type="submit" data-dojo-attach-point="button" data-dojo-type="hotplate.hotDojoWidgets.BusyButton" label="Create!" />' + 
'  </form>' + 
'</div>', 

onOverlayClick: function(){ 
this.onShow(); 
}, 
onShow: function(){ 
var that = this; 
// By default, this widget is overlayed 
this.set( 'overlayed', true ); 
this.set( 'overlayClickable', false ); 
var workspaceSettings = stores('workspaceSettings', { workspaceIdCall: vars['hotDojoAppContainer']['workspaceId'] } ); 
workspaceSettings.get('').then( 
function(res){ 
// OK things worked out: the overlay can go 
that.set( 'overlayed', false ); 
// Assign all of the received values to matching fields 
// TODO: Turn this into a function 
that.form._descendants.forEach(function( widget ) { 
console.log(widget); 
if( typeof( res.data[ widget.name ] ) !== 'undefined'){ 
widget.set('value', res.data[ widget.name] ); 
} 
}); 
}, 
function(err){ 
that.set('overlayClickable', true ); 
} 
); 
}, 

混合物:

define([ 
"dojo/_base/declare", 
"dojo/on", 
"dojo/dom", 
"dojo/dom-construct", 
"dojo/dom-attr", 
"dojo/dom-class", 
], function( 
declare 
, on 
, dom 
, domConstruct 
, domAttr 
, domClass 
){ 
return declare( null, { 
overlayed: false, 
overlayClickable: false, 
postCreate: function(){ 
var that = this; 
this.inherited(arguments); 
// Create the overlay widget, place it as first in the widget 
var overlay = domConstruct.create('div', { 
className: 'overlay', 
style: { 
'position': 'absolute', 
'top': 0, 
'bottom': 0, 
'left': 0, 
'right': 0, 
'z-index': 99, 
'display': 'none', 
'background': 'rgba(0,0,0,0.32)' 
} 
} ); 
domConstruct.place(overlay, this.domNode, 'first'); 
// Set the overlayNode attribute of the widget 
this.overlayNode = overlay; 
// Wire the click of the mouse to the object's "onOverlayClick" 
on( this.overlayNode, 'click', function(e){ 
if( that.overlayClickable && typeof( that.onOverlayClick ) === 'function' ) { 
that.onOverlayClick(e); 
} 
}); 
}, 

// Set the widget as "overlayed" or 
_setOverlayedAttr: function( value ){ 
this._set('overlayed', value); 
if( value ){ 
domAttr.set( this.overlayNode, { style: { display: 'block'} } ); 
} else { 
domAttr.set( this.overlayNode, { style: { display: 'none'} } ); 
} 
}, 
_getOverlayedAttr: function(){ 
return this.overlayVisible; 
}, 

// Set the widget as clickable or not 
_setOverlayClickableAttr: function(value){ 
console.log("Set to clickableeeeeeeeeeeeeeeeeeeeeeeeeeeeee!"); 
this._set('overlayClickable', !! value); 
if( value ){ 
console.log("1"); 
domClass.add( this.overlayNode, 'overlayClickable' ); 
} else { 
console.log("2"); 
domClass.remove( this.overlayNode, 'overlayClickable' ); 
} 
}, 
_getOverlayClickableAttr: function(){ 
return this.overlayClickableAttr; 
} 

});  
}); 

最新更新