Constraints

出自OpenFace

跳转到: 导航, 搜索

Prev                                                                          Next

                              第十九章 约束

                             第四部分 进级概念


 

目录

约束定义

  在lzx中约束是使视图属性保持其它某个属性的功能。     约束可以帮你快速的创建依赖关系而不需要编写大量的代码。您可以指定某个视图的大小或位置同另一个视图相关联。指定的元素只有在某些特定情况下才能被显示,并且这些条件被描述成一个简单的表达式,同样约束也可以用于自定义属性。

创建和删除约束的语法

可以使用下面两种方法来创建约束:

  在标签中使用${}语法来绑定到另外一个属性值。

  在脚本中使用applyConstraint()函数。

  在脚本中,使用delegates。

在标签中创建约束

  约束的语法是:

${expression} 

  $表示绑定符

  括弧{}加里面内容构成一个表达式用来表示当前视图的属性由表达式决定


代理和约束

  Laszlo应用的脚本中可以使用代理(delegate)来使函数和事件发生关联。当事件被触发,函数即被调用。

  上面约束的表达式也可以写在这样的脚本中:

<handler name="oninit">  
 var width_del = new LzDelegate(this, "updateMyWidth");
 width_del.register(parent, "onwidth");
</handler> 
<method name="updateMyWidth">
 this.setWidth(parent.width);
</method>


  你可以在第22章 阅读关于代理(delegates)的信息

运行时约束

  每当属性的值改变时,便触发相应的事件。因为一个属性的值依赖于另外一个和多个属性值的约束,当被依赖的属性接受到事件时需要重新计算它的值。

考虑:

<view name="someView" width="${someAttribute + someOtherAttribute}" /> 

  当someAttribute或someOtherAttribute的属性值改变时,someView的width属性需要重新计算它的值。

例如:

<view name="beatles" width="${this.paul.width + 28}">
  <view name="paul">
      <handler name="onkeydown" reference="LzKeys">
           paul.keyhandler();
      </handler>
  </view>
</view>


  beatles宽度的大小随paul's宽度大小的改变而改变。它的约束表达式为${this.paul.width+28}。

  这个例子不重要,但是它为你声明的彼此相关的对象结构提供有力的证据。约束在LZX编程中是个基本概念,并且根据约束重要的地位也是思考LZX规范系统行为必不可少的知识内容。


建模实时系统约束

  你可以把约束作为建模实时系统的相互关系。一个约束表达式可以建立两个对象之间的联系。

  在下面的例子中,蓝色正方形是否能显示是同<text>文本是否能显示相联系的。如果text显示,则蓝色正方形能显示。触发键盘事件可以改变text是否显示。

Example 19.1. 当text显示时,蓝色正方形则显示

<canvas height="120">
    <simplelayout/>
    <text id="cb" text="Show Blue Square"/>
    <view visible="${cb.visible}" width="30" height="30" bgcolor="blue" >
       <handler name="onkeydown" reference="LzKeys" >
           cb.setVisible(!cb.visible);
       </handler>
    </view>
</canvas>

事件和依赖

  每一个约束有一个或一个以上的依赖。举例来说,约束表达式:

width="${parent.width}"

  创建一个依赖于父结点宽度的属性。在第21章对与任何时候设置setAttribute("whateever",4)时并会触发相应的事件会有解释。在上面的例子中创建了宽度属性。任何时候通过setAttribute()设置属性值时,并会触发onwidth事件。

  当你使用一个约束表达式时,只要受约束的事件被出发,并会自动调用其事件函数。

多重依赖

  约束可以依赖于多个属性。在下面的代码中,width属性依赖于其父结点的width和bordersize属性。其中任何一个属性改变都会引起其宽度的改变。在这个例子中,parent.width被父结点的宽度属性代替,当parent是整个view标签。

width="${parent.width - parent.bordersize * 2}"


  在下面的例子中,对在运行时进行多个属性的绑定。蓝色矩形的大小由父结点的属性决定

Example 19.2. Multiple Dependencies

<canvas height="300" width="300">
   <view width="400" height="200">
      <attribute name="bordersize" type="number" value="10"/>
      <view y="20" name="editor" >
           <text y="-4" resize="true">bordersize:</text>
      </view>
      <view bgcolor="0xFFC834" y="80" width="${parent.width}" height="10" />
      <view x="${parent.bordersize}" y="80" width="${parent.width-parent.bordersize*2}"
           height="10" bgcolor="blue" />   
   </view>
</canvas>

循环依赖

  当属性A依赖于属性B,属性B依赖于属性A,并构成了循环依赖关系。例如,在下面的Laszlo应用中,红色正方形与蓝色正方形中的y值相互依赖,这在LZX中是非常自然的事情。

Example 19.3. Circular Constraints

<canvas height="120">
 <view name="redview" bgcolor="red" width="40" height="40" y="${blueview.y}"/>
 <view name="blueview" bgcolor="blue" width="40" height="40" y="${redview.y}"/>
 <simplelayout spacing="40" axis="x"/>
</canvas>


  它是怎样工作的呢?当红色view中的y值改变时,会触发ony时间。蓝色view监听到红色view的ony事件并会改变自己的y坐标,同样红色view监听到蓝色view的ony事件,然而,它并没有响应该事件,因为handler事件在每次事件时只能被调用一次。

性能考虑

  编写用户界面代码和管理非视觉的(抽象的)应用状态某些情况下的约束是非常有效的方式。象其他的代码一样,您想要了解潜在的性能,以及当要得到同样的效果时最好使用约束而不提倡交替的方法。


约束求值声明

  很多时候,您想用约束表达式来创建应用的初始状态,当时在使用中您不需要属性进行自动更改。在这种情况下,您需要通过表达式来设置在什么时候更改。

  当您用${..}语法来写一个约束时(如以下的例子),when="always"是缺省的。

<view width="${parent.width}" height="10" bgcolor="yellow"/>


使用Layouts替代约束

  约束对设置views的大小和位置非常有用。然而,如果您有很多view只在同样的信息上不同,最好是使用一个<layout>而不是写一个复杂的约束机制。在openlaszlo平台上有好几个layouts可以使用,您也可以根据自己的需要进行设置。见第14章,布局和设计,更多的关于该主题信息。

使用事件和函数替代约束

 通常,如果您需要基于单个依赖上需要更新不同的事情,最好的办法是在某个属性上通过适当的行为来触发设置的函数。


                                Home

Prev                                                                          Next