Ultrashock Tutorials > Flash MX > Common Component Issues  
 
by: Gregory Burch, http://radio.weblogs.com/0107886/

Source File

 
Common Component Issues
 


This article’s content is based on common issues with components that have been seen in the Flash community. If you feel something should be added, send an email to gburch@squarelabs.com with your suggestions.

Coding Practices

When creating components it is always best to stick to good coding practices. For components to be useful they must be reusable and extensible. This section will not cover all the good coding practices, but rather, it will cover a few that people have had problems with, for example: using classes for your components, using Object.registerClass(), and remembering to create member variables, not just instance variables.

The Importance of Classes

Many people still try to create components based on how they created smart clips in the past. Components are best based on classes, which give you a lot of advantages. One benefit is that the component code is stored more efficiently. The functions for the component methods live in only one place—the class prototype—not in every instance of the component. By contrast, with the smart clip approach, each instance declares its own copies of the functions, increasing ram usage.

And probably the most important advantage is extensibility. By using classes, new components can take advantage of inheritance, gaining abilities from existing components. This adds to their reusability since components can be extended to do things that were previously outside their power. And finally, if you don’t use classes, you can’t take advantage of the #initclip directive which means you will have to do ugly hacks like back in the Flash 5 days.

Object.registerClass()

If you are making components, it's crucial to understand Object.registerClass(). Here is a quick review: Object.registerClass() allows you to associate the linkage of the component movie clip(a string identifier) with a class. That way, when the movie clip is dragged on stage or attached, it will be an instance of the class you define. Its syntax is as follows:

Object.registerClass(stringname, classref);

If you have a MovieClip with the linkage name “FComponentSymbol” and a class FComponentClass, the Object.registerClass() syntax would be as follows:

Object.registerClass(“FComponentSymbol”,FComponentClass);

#initclip

Purpose
The purpose of the #initclip directive is so that you can define the order in which classes are defined. You define this by putting a number after #initclip:

#initclip 0

This fixes the problem that arose in Flash 5 where you would have to wait a frame per level of nesting for the component to initialize. So when working with inheritance you have to at least set this number to Super class plus one. But I like to leave my self some room for further expansion so I set it to plus three or so.

//Foo Movieclip
#initclip 0

Foo = function(){}
Foo.prototype.myVar = true;

#endinitclip

//Bar Movieclip
#initclip 3

Bar = function(){
   super();
   trace(this.myVar);
}

//we set #initclip Foo + 3
Bar.prototype = new Foo();
Bar.prototype.myVar = false;

#endinitclip

Always remember to define your classes in #initclip when working with components, if you do not the class will be redefined in every instance of the component.

Scope
First time component developers usually miss the fact that anything within the #initclip directive is actually scoped to _level0 this means that you MUST use this when referring to class members and MovieClip properties. In Flash anything not prefixed with this is scoped to where it is defined. So when changing the _width property of your component you must say this._width. So if you are having trouble changing certain properties and executing certain methods, this is the first thing to check.

Naming Conventions

You will probably want to follow Macromedia’s standard for naming. Looking at their components, they usually do the following:

  • The name of the symbol in the library can be anything you want (minding illegal characters of course)
  • The linkage name of the symbol is the name of the symbol prefixed with an F (for Flash) and a suffix of Symbol. So if you had a component “Scrollbar” its linkage would be “FScrollbarSymbol”
  • The class that defines your component will be the symbol name with a prefix of F and a suffix of Class. For the Scrollbar it would be “FScrollbarClass”

Versioning

Macromedia does several things when it comes to versioning, so I am going to take an educated guess on the best way to do things. First of all, it's always best to keep the version in a comment at the beginning of the code block. I usually use JavaDoc style to comment my code. Here is an example of a class description:

/**
* @class FSomeComponentClass
* This component does something cool.
*
* @author GBurch
* @version 1.0.6
*
* @see SomeOtherClass
*/

That way developers can easily see inline to the code what version they have. This is especially good when using external includes. The other thing you will want to do is to keep something in the library that states its version. Macromedia’s way of doing this is to create a symbol in Flash UI Components/Core Assets/Version and name the symbol “Version – Your Component Name” in this symbol create a TextField and put on the first line the component name, on the second line put version info and date. Macromedia uses a letter and then a two-digit number to define version. Such as “b07” I think b is the release and 07 is the minor version. Below is a screenshot of how this looks.


Why do the Macromedia components show up at the top?

Simple! Put a space in front of your component name in the library. This will make it appear above all the folders.

Nesting Components

Nesting components can be quirky if it is your first time doing it. You have to use the attachMovie() method when working with them.

Attaching Movieclips
As was just discussed in the previous section, #initclip runs before everything else. This means it runs even before any content placed at author-time. A common mistake is to place the components your component uses at author-time and expect to have access to it at runtime within the component. You cannot do this; instead you must attach the components you need at runtime.

Extensibility Tip
Many times, the components you are nesting are common components, such as scrollbars, listboxes, and comboboxes. You will gain a little extensibility if you do not hardcode the linkage ids’ in the component. You can just as easily put this in the prototype object so that later on, subclasses can change this id without a problem (as long as the new component has the same methods and p roperties) Below is an example:


#initclip 0
function MixedComponentClass(){
  
   this.attachMovie(this.scrollbarID,"scrollbar_mc",this.depth++);
   var x = this.scrollbar_mc._width;

   this.attachMovie(this.comboboxID,"combobox_mc",this.depth++,{_x:x});
   x+=this.combobox_mc._width;

   this.attachMovie(this.listboxID,"listbox_mc",this.depth++,{_x:x});

}

MixedComponentClass.prototype = new MovieClip();

Object.registerClass("MixedComponentSymbol",MixedComponentClass);

MixedComponentClass.prototype.scrollbarID = "FScrollBarSymbol";
MixedComponentClass.prototype.comboboxID = "FComboBoxSymbol";
MixedComponentClass.prototype.listboxID = "FListBoxSymbol";
MixedComponentClass.prototype.depth = 0;

#endinitclip

You can find the complete source in the Nesting.fla file.

Live Preview

Live Preview is a very common issue for component developers and a seperate article/tutorial has been written on this topic. Click here to be taken to the Live Preview tutorial.

 
©2002 Ultrashock.com Inc. - All rights reserved