所以我已经通过SO进行了大量的搜索,但却找不到这个问题的答案。我的符号库中有一个动画片段,它是为actionscript导出的,我为它编写了一个自定义类。除了在我将movieclip添加到舞台后尝试访问自定义私有属性时,它的效果非常好。下面是一个例子:
package {
public class MyMovieClip extends MovieClip {
private var _isEnabled:Boolean = false;
public function MyMovieClip():void {
trace(this);
}
public function set isEnabled( b:Boolean ):void {
_isEnabled = b;
}
public function get isEnabled():Boolean {
return _isEnabled;
}
}
}
然后我有另一个类,我将一个movieclip的实例添加到循环中的舞台:
package {
public class MyOtherClass extends MovieClip {
public var myMC:MyMovieClip;
public var docClass:*;
public function MyOtherClass( docRef:* ):void { // passing in a reference to the DocumentClass so I can access the stage
docClass = docRef;
init();
}
public function init():void {
for(var i:int=0; i<6; i++) {
var myMC:MyMovieClip = new MyMovieClip; // instantiate the movieclip which is exported for actionscript and has a custom class
//set a few native properties
myMC.name = "myMC" + i; //setting the name so I can reference this movieclip after it's been added to stage
myMC.y = myMC.height * i + 20;
myMC.x = 20;
myMC.alpha = .7;
}
dispatchEvent(new Event(MyOtherClass.MOVIECLIPS_ADDED)); // just to be safe, let's dispatch a custom event when all movieclips have been added
}
public function traceEnabled():void {
trace(docClass.stage.getChildByName("myMC1").isEnabled); // this throws: 1119: Access of possibly undefined property isEnabled through a reference with static type flash.display:DisplayObject
}
}
}
最后我在我的文档类中实例化了MyOtherClass:
package {
public class DocumentClass extends MovieClip {
public var myOtherClass:MyOtherClass;
public function DocumentClass():void {
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
public function onAddedToStage(e:Event):void {
myOtherClass = new MyOtherClass(); // upon instantiation, init is called in MyOtherClass and all of my movieclips are added to the sage
}
}
}
是什么给出的?为什么我不能在将它添加到舞台后访问MyMovieClip属性isEnabled?还有另外一种方法吗? (提前感谢您的帮助)
答案 0 :(得分:0)
DisplayObjectContainer
内部的所有子项都被引用为DisplayObject
,因此当您使用getChildByName
时,它会返回一个DisplayObject。
要在不导致编译时错误的情况下访问自定义属性,您需要将getChildByName
的结果强制转换为自定义属性的类。请参阅下面的代码。
然而,这不是你唯一的问题(虽然这是错误的原因,一旦你纠正,你也会得到运行时错误。)
在你的创建循环中,你没有将myMC
添加到显示列表中,因此调用stage.getChildByName()将返回null,因为你的剪辑不在舞台上。
您也没有将myOtherClass添加到已发布代码中的显示列表中。
此外,实际上不需要存储对文档类的引用。只需在MyOtherClass
中添加addedToStage侦听器,并将处理程序设置为init。
这里有一些更新的代码
对于MyOtherClass
:
public function MyOtherClass():void {
if(stage){
init(); //if stage is ready, call init, if not wait for the added to stage event
}else{
addEventListener(Event.ADDED_TO_STAGE,init);
}
}
public function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE,init);
for(var i:int=0; i<6; i++) {
var myMC:MyMovieClip = new MyMovieClip;
myMC.name = "myMC" + i; //setting the name so I can reference this movieclip after it's been added to stage
myMC.y = myMC.height * i + 20;
myMC.x = 20;
myMC.alpha = .7;
addChild(myMC); //!!!! add to the displayList
}
dispatchEvent(new Event(MyOtherClass.MOVIECLIPS_ADDED)); // just to be safe, let's dispatch a custom event when all movieclips have been added
}
public function traceEnabled():void {
var myMC:MyMovieClip = this.getChildByName("myMC1") as MyMovieClip; //!!! cast it as MyMovieClip so you have access to all the properties/methods in that class
if(myMC){ //myMC will be null if the cast failed
trace(myMC.isEnabled);
}
}
/*
getChildByName is slow and cumbersome. Most people generally only use it for accessing things put on the timeline in the Flash IDE. Using events is a much better way of accessing your items. If traceEnabled was caused by a mouse event attached to myMC, then this would be a much better implementation:
*/
public function betterTraceEnabled(e:Event):void {
var myMC:MyMovieClip = e.currentTarget as MyMovieClip;
if(myMC){
trace(myMC.isEnabled);
}
}
和你的文件类:
public class DocumentClass extends MovieClip {
public var myOtherClass:MyOtherClass;
public function DocumentClass():void {
if(stage){
onAddedToStage(null); //most of the time stage is already populated in the constructor of your document class
}else{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
}
public function onAddedToStage(e:Event):void {
myOtherClass = new MyOtherClass(); // upon instantiation, init is called in MyOtherClass and all of my movieclips are added to the sage
addChild(myOtherClass); //add it to the displayList
}
}