`

Combining Tags and Script in LZX Programs (openlaszlo)

阅读更多

6. Combining Tags and Script in LZX Programs

As mentioned earlier, virtually all nontrivial LZX programs contain both (XML) tags and script. Tags are used declaratively, that is, to define objects and their attributes. Script is used procedurally, that is, to explicitly define a series of steps. Although the two kinds of code are liberally intermixed within LZX — for example, script can appear within tags — each syntax locally maintains its integrity.

So for example, within declarative LZX code, comments are denoted

<!-- XML comment -->

while within JavaScript, comments are denoted

// JavaScript comment

Thus LZX is similar to an alloy of two metals that do not chemically combine.

Because the declarative and procedural portions of a program can be so intertwined, it can be a little tricky, at first, to recognize them within a program. However, once you gain a little experience and begin to grasp the underlying logic of LZX you will find that you hardly notice the alternating syntaxes. The following paragraphs explain how and why to employ the two "flavors" of LZX. Consult the documentation for your IDE or text editor to learn how to use the LZX DTD or schema to give visual cues that indicate what portions of the program are in each syntax.

 

6.1. Name Mapping between Tags and Classes

The preferred normalized form of class names is lz.[tagname] where [tagname] is the name of a tag. So for example a if you created a class called "bob":

<class name="bob"/>

then from the point of view of JavaScript, this would be an lz.bob object.

In earlier versions of LZX (before OpenLaszlo 4), there was an asymmetric mapping between tag and class names, often of the form LzFoo <—> <foo>, as in the correspondence between, say the class name lz.view and the tag name <view>. (Notice in lz.view the mixed case, and the absence of the period between lz and the tag name.) Also there was a distinction between LFC classes and user-created classes. The new lz.foo form is consistent across LFC classes and user-created classes. The old forms will still work, and they appear throughout this documentation and in example code. At some point, however, the old forms will probably be deprecated, and it would be a good practice to adopt the new form in your code.

 

6.2. How to Combine Tags and Script

Let's start by making a distinction between what is syntactically allowable and what is meaningful.

 

6.2.1. What's Allowable

Remember that all LZX programs are well-formed XML files. That means that all portions of the program, including embedded JavaScript, must conform to XML rules. Therefore where JavaScript uses characters that are meaningful to XML, such as the left angle bracket <, you must make sure that those characters don't confuse the XML parser. You can do that in either of two ways:

  • by explicitly escaping delimiter characters with an entity reference. (For example, the entity reference for the left angle bracket is &lt;).

  • by using the XML CDATA construct to define a block of character data.

This is the sum total of rules for making sure that XML does not trip on JavaScript.

 

6.2.2. What's Meaningful

Although the admixture of two different sets of language rules in one language does create opportunities for confusion, it's fairly easy to recognize how LZX programs are structured, and what kind of code goes where. There are only a few contexts in which script code can appear in LZX programs. After you learn to recognize these contexts you are unlikely to be confused about what syntax applies. JavaScript is used:

  • between an opening and closing <script> and </script> tag;

  • between an opening and closing <method> and </method> tag;

  • between an opening and closing <handler> and </handler> tag;

  • with the double-quoted right hand value of an assignment statement within certain tags, such as oninit="script expression" .

 

6.3. When to Use Tags and When to Use Script

As we said earlier, most things that you can do in LZX can be done either with XML tags or JavaScript APIs, and mastering LZX requires developing a subtle understanding of how and when to use each. You will find, in general, that tags are best for computations that can be done at compile-time — such as laying out the canvas — and script is best for run-time things, such as responding to user input. But in order for you to make any use of that information you need to understand what is done at compile time and what is done at run time, and much of that is under your control, and dependent on the problem you're trying to solve.

In other words, there is no simple set of unambiguous rules that tell you when to use tags versus when to use script. But there are, however, design patterns common to all well-made LZX programs.

Remember, LZX is primarily a language for manipulating visual objects called views. So the question of when to use tags versus script is usually asked in the context of the creation of views and manipulation of their attributes. Script can be used for other things, such as global functions, but in those instances the need to write procedural code (i.e., script) is usually clear-cut. The finesse part has to do with manipulating views and their attributes.

For example, a simple two-word constraint might express a relationship between views that would require thirty lines of code to express. Most of the time the constraint is the better programming solution. But not always.

Although there are no absolutes, there are some general principles that define best practice in LZX development:

  • Use tags when that is the only option.

  • Use JavaScript when that is the only option.

  • If something can be done with either tags or script, use tags (unless there is a good reason not to).

Each of these principles is described briefly below.

 

6.3.1. Use tags when that is the only option

There are certain tags that perform functions that cannot be done using script. For example, the root node (and enclosing tag) of every LZX program is <canvas> . Every LZX program begins with <canvas> and ends with </canvas>; there is no alternative structure using script. Similarly there are no script equivalents for <splash> , <method>, <attribute>, <resource> , <font> , and several other tags. Moreover, within certain tag definitions there are certain attributes that can only be set in the tag.

 

6.3.2. Use JavaScript when that is the only option.

There are several JavaScript APIs that perform functions that cannot be done using tags. For example, LzDelegate, lz.event, LzParam and similar APIs perform operations that cannot be done using tags. Similarly, there are certain attributes of objects that can only be referenced by script, even for objects that were created with tags. For example, consider

<view name="franklin">

There is an attribute, franklin.subviews, that can be accessed by script; it is not possible to set or access that attribute in a tag.

 

6.3.3. If something can be done with either tags or script, use tags.

In the large number of cases where it is possible to do something using either tags or views, it is generally better to use tags. For example you can create a new view called "sam" using tags

<view name="sam">

or script

sam = new lz.view();

When you use the tag syntax you can quite naturally create hierarchies of nested subviews, define attributes as constraints, and lay out your code in a way that helps you conceptualize the placement of views on the canvas. Achieving any of these results in pure JavaScript would be a colossal pain and negate much of the benefit of the language. Learning to think in LZX means learning to think in terms of views that act nearly autonomously according to the constraints you establish at their creation.

 

6.3.4. Unless there is a good reason not to.

Sometimes it's better to write procedural code instead of declarative code. This may become necessary, for example, to achieve optimal performance: multiply-constrained systems can sometimes become CPU bound. Other times procedural code may make your program's behavior easier to understand: complex rule-based view systems sometimes become inscrutable.

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics