使用 Dojo 1.6.1。
更新:这是一个 jsfiddle http://jsfiddle.net/E4EaM/1/
创建了一个包含一些字段的表单。
this.projectServiceidField = new dijit.form.TextBox({
label: 'idField'
, name: 'project_service_id'
, required: true
, type: 'hidden'
}).placeAt(this.domNode);
this.projectServiceEquipmentSourceAddress = new dijit.form.FilteringSelect({
name: 'source_address_id'
, required: true
, store: model.CustomerAddressesPairsView
, searchAttr: "name"
, style: "width: 40ex;"
});
当所有的小部件值都被设置时,应用程序需要得到通知。为此,将创建一个 Deferred 对象,并在小部件的“值”属性上使用有状态监视。 Deferred 对象都放在一个 DeferredList 中。一旦 widget 的值被初始设置,watch 就会被移除,它的 Deferred 对象会被解析。
//loop
w.deferred = new dojo.Deferred();
da.push(w.deferred);
// Watch the widget's value
w.initWatch = w.watch('value', function(property, oldValue, newValue) {
w.initWatch.unwatch();
console.debug(w.name, 'property:', property, 'oldValue:', oldValue,'newValue:', newValue,'w.get(\'value\'):', w.get('value'));
w.deferred.resolve();
});
// Set the widget's value
w.set('value', value);
//endloop
var dl = new dojo.DeferredList(da);
当 DeferredList 被解析时,所有的小部件值都应该已经设置。
dl.then(
function() {
dojo.forEach(da, function(d) {
console.debug(Date.now(), d);
})
console.debug(Date.now(), dl, 'DeferredList resolved -------->', form.getValues());
console.debug(form.getValues());
}
);
但是,它并没有像预期的那样工作。特别是执行 xhr 请求的字段。以下是在“值”更改事件中生成的值。
project_service_id 属性:value oldValue:newValue:1025 w.get('value'):1025
source_address_id property: value oldValue: newValue: 59 w.get('value'):
source_address_id 应该有一个值 59 但当我 w.get('value') 时,它不等于 newValue。不应该吗?
如何确定小部件的值何时已设置?为什么 value == w.get('value') 不是紧跟在 w.set('value', value) 之后?
如果 w.set('value', value) 不是真正设置值,它不应该返回一个延迟的值吗?
不应该只在设置值后触发?
Dojo 版本:
在 Dojo 1.6.1 中失败。 Watch 并不总是触发 w.get('value') != newValue 当它触发时。
在 Dojo 1.7.2 中失败更少。 watch 仍然不会总是触发,但至少 w.get('value') == newValue。
最佳答案
在 irc 上与 richard 讨论后,我们发现 dojox.data.QueryReadStore
和 dijit.form.FilteringSelect
之间存在一些细微差别,这会阻止如果商店尚未完成 fetch
,则 "value"
watch 回调将被触发。可行的解决方案是先执行 fetch
,然后在 onComplete
回调中创建小部件 - 参见 http://jsfiddle.net/neonstalwart/dEC7M/
相关部分是
customerAddressesPairsView.fetch({
onComplete: function() {
var w = new dijit.form.FilteringSelect({
name: 'source_address_id',
required: true,
store: customerAddressesPairsView,
searchAttr: "name",
style: "width: 40ex;"
}, 'sourceAddress');
var handle = w.watch(function(property, oldValue, newValue) {
console.log(property, oldValue, newValue);
});
w.set("value", value1);
console.debug('Value set to ' + value1);
console.debug('Immediate get returns:', w.get('value'));
console.debug('Direct access returns: ' + w.value);
}
});
关于Dojo Stateful watch 方法在实际设置值之前触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9831404/