高级选项卡面板向导

时间:2016-10-18 06:03:27

标签: javascript extjs extjs6

我有一个相当高级的TabPanel向导,我正在努力,我似乎​​无法让它正常行事。基本上,我有4个选项卡...每个选项卡都是自己的表单,因为选项卡需要对自身进行验证,因此它可以确定是否需要禁用其右侧的选项卡,或者是否应启用下一个选项卡。

我遇到的主要问题是,非渲染选项卡认为它是有效的,实际上,它的字段设置为allowBlank: false,并且它具有空值。然后是倒数,我有一个值集,但它认为它是无效的。

另一个怪癖是,我必须在选项卡面板加载时调用this.getViewModel().notify() ...否则,当我检查初始有效性时,我的激活表单认为它无效...虽然,我相信这有关有约束力和延迟,所以我现在可以解决这个问题。

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

In my Fiddle,你会看到启用了3个标签,实际上它应该是已启用的4个标签,因为第3个标签包含其模型的数据,但标签认为它无效。由于选项卡认为它无效,它会重新触发我的checkValidity方法,因为我检查isValid是否为false(如果当前选项卡无效,则禁用右侧的任何选项卡,并且用户被强制命中继续,这是由设计)。在控制台中:

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

有没有人有任何见解?我是不是真的错了?

1 个答案:

答案 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中获取值,并在制作它们时将它们明确地分配给字段。这样,它们最初以正确的状态创建,因此通过了有效性检查。