我有一个相当高级的TabPanel
向导,我正在努力,我似乎无法让它正常行事。基本上,我有4个选项卡...每个选项卡都是自己的表单,因为选项卡需要对自身进行验证,因此它可以确定是否需要禁用其右侧的选项卡,或者是否应启用下一个选项卡。
我遇到的主要问题是,非渲染选项卡认为它是有效的,实际上,它的字段设置为allowBlank: false
,并且它具有空值。然后是倒数,我有一个值集,但它认为它是无效的。
另一个怪癖是,我必须在选项卡面板加载时调用this.getViewModel().notify()
...否则,当我检查初始有效性时,我的激活表单认为它无效...虽然,我相信这有关有约束力和延迟,所以我现在可以解决这个问题。
我可以使用deferredRender: false
来解决这个问题,但我不想这样做,因为在我的实际应用程序中,每个选项卡中都有相当多的标签,因此效率不高。
In my Fiddle,你会看到启用了3个标签,实际上它应该是已启用的4个标签,因为第3个标签包含其模型的数据,但标签认为它无效。由于选项卡认为它无效,它会重新触发我的checkValidity方法,因为我检查isValid是否为false(如果当前选项卡无效,则禁用右侧的任何选项卡,并且用户被强制命中继续,这是由设计)。在控制台中:
有没有人有任何见解?我是不是真的错了?
答案 0 :(得分:2)
这种情况正在发生,因为视图模型和绑定不会按照您的想法执行。
首先 - 当您创建这样的字段时:
{ fieldLabel: 'Value3', xtype: 'textfield', name: 'value2', allowBlank: false,
bind: { value: '{model1.value2}' }
}
该字段最初创建时没有任何值。那是因为你还没有定义任何价值 - 你已经限制了它。并且绑定不会立即生效。出于性能原因,它通常不会被绑定直到呈现选项卡(这就是为什么不推迟渲染适用于你)
这样做的最终结果是,当您检查Tab 3的有效性时,它会失败,因为尚未绑定的值。如果将第24行的日志语句更改为:
,则可以更清楚地看到这一点console.log(form.owner.title, form.getValues(), form.owner.rendered, isValid)
通过此更改,当您首次呈现选项卡面板时,您将获得此输出(无评论):
afterrender // triggers the view model to notify.
activate
checking
tab1 Object {value: "blah"} true true // Value bound because it was rendered.
tab2 Object {value: ""} false true
tab3 Object {value2: ""} false false // Value not bound because it is not rendered
checking
tab4 Object {} false true // No properties yet...
请注意,如果您没有拨打this.getViewModel().notify()
,那么您会收到此输出:
afterrender
activate
checking
tab2 Object {} false true
tab3 Object {} false true
tab4 Object {} false true
tab1 Object {value: "blah"} true true
请注意不同的订单。
那么这里发生了什么?好吧,首先 - 在绑定字段值之前,选项卡上的各个表单没有数据。没有字段,它们被认为是有效的。
当你调用isValid时,它会强制定义字段 - 但它们仍然没有被绑定。因此它们没有价值,而在tab3的情况下,它使它无效。由于tab3无效(尚未绑定数据),因此未启用选项卡4.
如果您没有调用viewModel.notify()
,那么在第一次调用checkValidity()
期间,tab1尚未绑定任何数据。因此,它无效(它有字段,但没有值),并且没有启用tab2等。
有效性最终都被整理出来 - 但是你只检查从true变为false时的状态 - 而不是false变为true。这给出了你看到的行为。
如何解决这个问题?可能有几种方法。可能最有效的方法是在面板的initComponent期间从viewModel中获取值,并在制作它们时将它们明确地分配给字段。这样,它们最初以正确的状态创建,因此通过了有效性检查。