高级选项卡面板向导

Advanced tab panel wizard

本文关键字:向导 高级选项      更新时间:2023-09-26

我有一个相当先进的TabPanel向导,我正在工作,我似乎不能让它正常工作。基本上,我有4个标签…每个TAB都是自己的表单,因为TAB需要对自己进行验证,所以它可以确定是否需要禁用其右侧的TAB,或者是否应该启用下一个TAB。

我遇到的主要怪怪是,一个非渲染的选项卡认为它是有效的,而事实上,它的字段被设置为allowBlank: false,它有一个空值。然后是反向的,我有一个值集,但它认为它是无效的

另一个怪癖是,当标签面板加载时,我必须调用this.getViewModel().notify()…否则,当我检查初始有效性时,我的激活表单认为它无效……虽然,我相信这与绑定和延迟有关,所以我现在可以处理这个问题。

我可以使用deferredRender: false来解决这个问题,但我不想这样做,因为在我的实际应用程序中,每个选项卡都有相当多的内容,所以性能不高。

在我的小提琴中,你会看到3个选项卡被启用,而实际上,它应该是4个选项卡被启用,因为第三个选项卡有来自其模型的数据,但选项卡认为这是无效的。因为选项卡认为它是无效的,所以它重新触发我的checkValidity方法,因为我检查了isValid是否为假(这是为了在当前选项卡无效时禁用右边的任何选项卡,并且用户被迫按下继续,这是设计的)。在控制台中:

  • Tab3认为它无效,这是不正确的,因为它被设置为allowBlank: false,但是它有一个绑定值
  • Tab4将认为它是有效的,这不是真的,因为它被设置为allowBlank: false并且没有值

有人有什么见解吗?我这么做是不是大错特错了?

这是因为视图模型和绑定并不像你想象的那样。

第一个-当你创建一个像这样的字段:

{ fieldLabel: 'Value3', xtype: 'textfield', name: 'value2', allowBlank: false,
  bind: { value: '{model1.value2}' }
}

字段最初创建时没有值。这是因为你没有定义任何值,你只是限定了它。而且绑定不会立即生效。出于性能原因,它通常不会被绑定,直到选项卡被渲染(这就是为什么不延迟渲染为您工作)

这样做的最终结果是,当您检查表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是无效的(还没有数据绑定),所以tab 4没有启用。

如果你没有调用viewModel.notify(),那么在第一次调用checkValidity()时tab1还没有数据绑定。因此,它是无效的(它有字段,但没有值),并且tab2等没有启用。

有效性最终都被整理出来了——但是你只检查从真到假的状态——而不是从假到真。它给出了你所看到的行为。

如何解决这个问题?可能有几种方法。可能最有效的方法是在面板的initComponent期间从viewModel中获取值,并在创建它们时显式地将它们分配给字段。通过这种方式,它们最初以正确的状态创建,从而通过有效性检查。