0

我需要精确指定 GWT 排列并控制其中的变化(每个组合支持的属性值),但很难找到详细的行为规范。

在我的实验中,我了解到我必须注意创建 set-property ... when-property-is 循环,即使这些循环是“稳定的”——即它们不会改变循环的任何部分,只需“确认”它. 这限制了我的能力,所以我决定尝试另一种方式 - 定义一个全新的属性,(只是)例如:

  <define-property name="precise.permutation" values="webkit,gecko,ie,unsupported"/>

...然后有类似的东西:

  <set-property name="precise.permutation" value="webkit">
    <!-- ... custom conditions ... -->
  </set-property>
  <set-property name="precise.permutation" value="gecko">
    <!-- ... custom conditions ... -->
  </set-property>
  <set-property name="precise.permutation" value="ie">
    <!-- ... custom conditions ... -->
  </set>
  <set-property name="precise.permutation" value="unsupported">
    <!-- ... custom conditions ... -->
  </set-property>

...然后我尝试将其限制为除不受支持之外的所有内容,该示例用作示例但完全违反直觉,因为它使用与上述相同的 set-property 标记:

  <set-property name="precise.permutation" value="webkit,gecko,ie" />

我还必须折叠其他属性以确保它们不会导致额外的排列。

不幸的是,这似乎没有按预期工作(使用 GWT 2.8 RC2 进行了尝试)。即使“不受支持的”排列没有出现(这是需要的),它的属性组合也会重新出现在其他排列中(这是不需要的)。

有人可以帮我找到关于此的权威和完整的文档或帮我解决这个问题吗?

谢谢!

4

1 回答 1

2

我仍然没有找到详细的文档,但我已经做了大量的实验并得出了以下结论......

(注意:我的示例使用了我开发的 Sencha GXT 中的一些概念)

<define-property> 用于定义属性及其可能的值,但对于实际使用的值而言,这并不是最后的决定。*.gwt.xml 文件的层次结构中的每个属性都应该有一个这样的定义。

<set-property> 不会将属性设置为 A 值,但会创建一种规则,其中包含该属性的 POSSIBLE 值的集合(理想情况下是 <define-property> 中定义的子集)。给定属性的最后一个 <set-property> 声明获胜。当心!如果您在 <inherits> 之后使用 <set-property> (继承模块),您可能/将覆盖您继承的任何规则。请注意,有条件规则和无条件规则。例如,

<set-property name="gxt.user.agent" value="ie10, ie11, gecko1_9, safari5, chrome"/>

... 将无条件声明,在确定排列时,属性“gxt.user.agent”可以具有任何列出的值。反过来,

<set-property name="user.agent" value="safari">
  <any>
    <when-property-is name="gxt.user.agent" value="safari5" />
    <when-property-is name="gxt.user.agent" value="chrome" />
  </any>
</set-property>

当“gxt.user.agent”是“safari5”或“chrome”时,将声明 user.agent 只能是“safari”。顺序似乎很重要,因此您需要在依赖项规则之后声明依赖属性的规则。循环依赖会使编译失败。您可以创建许多条件规则,只要它们不相互矛盾。我还不知道如果他们这样做会发生什么,但我猜最后宣布的人会赢。

请注意,条件规则还可以指定多个可能的值。例如(仅插图,可能与您的需求不符):

<!-- On desktops we do all browsers including IE -->
<set-property name="gxt.user.agent" value="safari5, chrome, gecko1_9, ie11">
  <when-property-is name="gxt.device" value="desktop" />
</set-property>
<!-- ... but on tablets and phones we exclude IE -->
<set-property name="gxt.user.agent" value="safari5, chrome, gecko1_9">
  <any>
    <when-property-is name="gxt.device" value="tablet" />
    <when-property-is name="gxt.device" value="phone" />
  </any>
</set-property>

您可以使用 <any> 和 <all> 创建复杂/复合标准。这些可以相互嵌套。

如何使用它来精确控制排列?您可能不需要它,但它帮助我从定义如下两个属性开始:

<define-property name="custom.use.case" values="case1, case2, ..."/>
<property-provider name="helix.product.mode"><![CDATA[   
    var useCase = ...; // JavaScript code to determine the use case
    return useCase;
  ]]>
</property-provider>
<define-property name="custom.permutation" values="perm1, perm2, ..."/>

第一个属性定义用例。上面我有一种方法可以在运行时确定它。您可能不会也可能会跳过它。它还可以作为定义其他所有内容的起点,因为我们可以根据用例定义所有其他属性。例如:

<!-- Case 1 restrictions -->
<set-property name="gxt.device" value="desktop">
  <when-property-is name="custom.use.case" value="case1" />
</set-property>
<set-property name="gxt.user.agent" value="chrome, safari5, gecko1_9, ie11">
  <when-property-is name="custom.use.case" value="case1" />
</set-property>
...

<!-- Case 2 restrictions -->
<set-property name="gxt.device" value="tablet, phone">
  <when-property-is name="custom.use.case" value="case2" />
</set-property>
<set-property name="gxt.user.agent" value="chrome, safari5, gecko1_9">
  <when-property-is name="custom.use.case" value="case2" />
</set-property>
...

<!-- Case 3 restrictions -->
<set-property name="gxt.device" value="tablet, phone">
  <when-property-is name="custom.use.case" value="case3" />
</set-property>
<set-property name="gxt.user.agent" value="safari5">
  <when-property-is name="custom.use.case" value="case3" />
</set-property>
...

etc.

接下来要做的是折叠除custom.permutation 之外的所有属性,因为我们只希望 custom.permutation 驱动排列:

  <collapse-property name="custom.use.case" values="*" />  
  <collapse-property name="gxt.device" values="*" />
  <collapse-property name="gxt.user.agent" values="*" />
  <collapse-property name="user.agent" values="*" />
  <collapse-property name="user.agent.os" values="*" />

这种方法允许对“排列”及其内部复杂性进行极细粒度的控制,有些人称之为“软排列”。每个可能的“custom.permutation”属性值都会有一个排列。如果您很好地设置了上述规则,则每个排列中只会包含所需的“软排列”。

请注意,实际排列和软排列都需要成本。拥有许多软排列(是否分组为实际排列)会降低编译性能和它们所在排列的运行时代码大小。不要忽略这一点,尤其是当您有许多属性时。实际排列具有更高的编译和链接时间成本(但与将许多软排列组合成分组的实际排列相比,拥有更多排列会减少每个排列的大小)。

如果使用 GXT,从版本 4 开始,您会注意到它添加了 gxt.device 属性,该属性具有桌面、平板电脑和手机等值。这导致我们的编译时间在升级到 GXT 4 后增加了大约 6-7 倍,因为我们的排列失控了。有些最终是为在 Mac OS 平板电脑上运行的 Internet Explorer 而设计的。您可以体会到对不存在的用例进行排列是多么浪费时间。通过实施上述方法,我们能够将 GWT 编译时间减少到原始时间的一半左右,或者比 GXT 4 升级后快 10-12 倍。

于 2016-09-13T04:33:19.273 回答