为了解决这个问题,我们可以把每个子页面都复制一份并重新编译。但这么做的话会占用更多的空间和网站流量。更好的办法是只编译第二个主SWF,把更新过的PageTitle类定义一起编译进去。然后在子页面在加载到子应用程序域的时候,这个类的定义就会被父域里的定义给覆盖。
原先所有子页面用的PageTitle类如下:
package { import flash.display.Sprite; import flash.text.TextField; public class PageTitle extends Sprite { private var title:TextField; public function PageTitle(titleText:String){ title = new TextField(); title.text = titleText; addChild(title); } } }编译到第二个主文件里的更新版本的PageTitle类:
package { import flash.display.Sprite; import flash.text.TextField; public class PageTitle extends Sprite { private var title:TextField; public function PageTitle(titleText:String){ title = new TextField(); title.text = titleText; <strong>title.selectable = false;</strong> // changed addChild(title); } } }把更新过的PageTitle类定义编译到新的主文件里面,并加载所有子页面到它们自己的子应用程序域中。
PageTitle; // 虽然没有直接用到PageTitle,但我们可以包含一个引用,让它被一同编译进来 // 加载子页面到它们自己的子应用程序域中 // 加载的SWF将会用父域里的PageTitle定义取代掉它们自带的 function addChildPage(url:String):void { var context:LoaderContext = new LoaderContext(); var current:ApplicationDomain = ApplicationDomain.currentDomain; context.applicationDomain = new ApplicationDomain(current); var loader:Loader = new Loader(); addChild(loader); loader.load(new URLRequest(url), context); }这种方法可以在不用重新编译子内容的前提下改变其中的类行为,这都是由于父应用程序域中的定义会覆盖子域中的定义的原因。
注意在上面的例子也可以省略LoaderContext的使用,效果是一样的。
即便子SWF无需用作多重使用目的,更新主文件中的定义也比更新所有子文件的更加简单。实际上,子文件中甚至可以完全不用包含这些定义,只依赖于主文件提供。这就是我们将在章节里将展开讨论的。
Separate Domains: Preventing Conflicts 域分离:避免冲突某些情形下,你可能不希望加载的子SWF内容被父应用程序域里的定义继承关系所影响。因为有可能你甚至不知道父域中存在哪些定义。不论哪种情况,最好都要避免主SWF和子SWF中的定义共享。在这种情况下,应该把子SWF的定义放到新的系统域的子域下。
系统域下的不同子应用程序域
由于父SWF和子SWF的定义之间没有继承关系,所以这时候即使存在相同的定义也不会引起冲突,因为二者属于不同的沙箱。
举个例子:比如你有个培训程序,通过加载外部SWF来代表不同的培训模块。这个程序已经有些年头了,许多开发者开发了成百上千个培训模块。这些模块,甚至培训主程序自身都是基于不同版本的基础代码库进行开发。所以主程序要保证自己使用的基础代码库不会对其他模块造成不兼容的情况。这就必须把这些培训模块加载到他们独立的系统域下的子域,而不是把他们加载到主应用程序域的子域下面。