我花了将近一周的时间来学习使用对象而不是数组。我以为它很容易调用它们并创建一些对象并设置它们的属性。但是我现在无法访问它们,我试过这个:
function onBoxClick(event:MouseEvent):void {
var str:String = event.currentTarget.name;
trace(str);
str = str.substring(str.indexOf("_") + 1);
trace(getChildByName("copy_" + str)); // trying to trace an object by name
}
我的问题是,是否有一种处理物体的实用方法,否则使用它们的目的是什么。
编辑:这是我用来创建动画片段和其他内容的功能:
function addBoxes(isUpdate:Boolean):void {
var copyOne:Object = getReadOnlyValues();
copyOne.name = "copy_" + num;
// Set default mc1 settings
var settings1:Object = copyOne.mc1Settings;
for(var num2:String in settings1) {
copyOne.mc1[num2] = settings1[num2];
}
// Set default mc1text settings
var settings2:Object = copyOne.mc1TextSettings;
for(var num3:String in settings2) {
copyOne.mc1Text[num3] = settings2[num3];
}
copyOne.mc1.x = nextXpos;
copyOne.mc1.name = "captionBox_" + num;
addChild(copyOne.mc1);
copyOne.mc1.addEventListener(MouseEvent.CLICK, onCaptionClick);
copyOne.mc1Text.name = "captionBoxText_" + num;
copyOne.mc1.addChild(copyOne.mc1Text);
// ---------------------------------------------------------------
// Set default mc2 settings
var settings4:Object = copyOne.mc2Settings;
for(var num4:String in settings4) {
copyOne.mc2[num4] = settings4[num4];
}
// Set default mc2text settings
var settings5:Object = copyOne.mc2TextSettings;
for(var num5:String in settings5) {
copyOne.mc2Text[num5] = settings5[num5];
}
copyOne.mc2.x = nextXpos;
copyOne.mc2.y = copyOne.mc1.height;
copyOne.mc2.name = "box2_" + num;
addChild(copyOne.mc2);
copyOne.mc2Text.name = "box2BoxText_" + num;
copyOne.mc2.addChild(copyOne.mc2Text);
copyOne.mc2.addEventListener(MouseEvent.CLICK, onBoxClick);
if (num / subunits is int) {
trace (num);
// createMc("normalBox", true);
}
nextXpos = nextXpos + copyOne.mc2.width;
// traceObj(copyOne);
// traceObj(getReadOnlyValues());
}
我在一个循环中调用了这个函数,因此我创建了许多动画片段。现在我无法访问对象'属性和他们的孩子(例如textfield)。
我在舞台上的对象:Movieclips和textfields
他们来自哪里:上述功能
我试图用它们做什么:跟踪动画片段和文本字段(由对象保持)以更改其子(文本字段)文本
会发生什么而不是我期望的:跟踪代码输出undefined而不是给我对象类型trace(getChildByName("copy_" + str)); // trying to trace an object by name
是否有一种实用的方法来访问名称为" copy_1"及其名称为" box2_1" (动画片段)?
答案 0 :(得分:1)
我看到的一个问题是" copyOne"对象已在" addBoxes"的范围内创建,因此它将不再存在于此函数之外。
另一个是你试图通过getChildByName访问一个Object,它只解决你正在调用的displayObjectContainer的displayObjects。
如果你想通过对象或MovieClip(它们都是动态样式的对象,可以让你根据需要添加属性)来松散地跟踪变量,只需使用MovieClip来存放你的值。在舞台上的movieClip将保留在内存中,直到从displayList(舞台)中删除。
另外,查看词典,这是一种基于键/值的方式来存储对象集合。
更好的是,如果您使用强类型自定义对象(创建自己的类来扩展MC,并添加自己的公共或私有方法和值),那么有一些好处,例如使用Vector(兼容的花式,快速数组)您选择的任何对象类型。)
答案 1 :(得分:0)
我真的不知道我是否理解你的问题,但正如@ozmachine在他的answer中说的那样,你不能使用getChildByName
,而是我认为你可以看看这可能会有所帮助:
var container:DisplayObjectContainer = this;
function getReadOnlyValues():Object {
return {
mc1: new box(),
mc1: {
name: 'mc1_',
alpha: 1,
x: 0,
y: 0,
width: 30,
height: 25
},
mc1Text: new TextField(),
mc1Text: {
text: 'test',
x: 0,
y: 0,
selectable: false,
multiline: false,
wordWrap: false
}
}
};
// create 5 objects
for(var i=0; i<5; i++){
container['copy_'+i] = getReadOnlyValues();
var obj:Object = getObjectByName('copy_'+i);
obj.mc1.alpha = 1;
obj.mc1.x = 0;
obj.mc1.y = 50 * i;
obj.mc1.width = 100;
obj.mc1.addChild(obj.mc1Text);
obj.mc1Text.text = 'test_' + i;
addChild(obj.mc1);
}
// get object by name
function getObjectByName(name:String):Object {
return container[name];
}
// change the text of the 4th button
stage.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {
var obj:Object = getObjectByName('copy_3');
obj.mc1Text.text = 'new text';
})
答案 2 :(得分:0)
Array和Object都是数据结构。 数据意味着某种形式的信息。 数据结构意味着以某种方式存储某种形式的信息。
数组和对象是存储信息的两种不同方式。
数组使用整数来标识数据。 用于标识数组中单个元素的整数称为索引
数组非常适合表示彼此相似的类似内容列表。
var names:Array = ["John", "Paul", "George", "Ringo"];
这通常意味着数组的元素属于同一类型,如上例所示。 但他们不必:
var numbers:Array = [42, "twenty-five", "XIIV"];
对于上面的例子,很容易回答这些问题&#34;四个披头士乐队的名字是什么?&#34;,&#34;你在发现期间偶然发现了什么不同的数字表示?穿过历史悠久的小镇?&#34;。其他问题更难或无法回答。 &#34;你在历史悠久的小镇偶然发现了什么罗马数字?&#34;
对象用名称标识数据。 用于标识对象的单个元素的名称称为属性
对象非常适合表示彼此属于的不同内容列表。
var paula:Object = {age:37, name:"Paula", hairColor:0x123456};
这通常意味着对象的元素具有不同的类型,如上例所示。 但他们不必:
var car:Object = {manufacturer:"Porsche", color:"red", sound:"wroooooom", soundOfDriver:"weeeeeeeeeeee"};
考虑到这一点,让我们看看您的代码,看看它是如何应用的。
大局是您有一个多次调用的函数addBoxes
。由于一个函数应该有一个目的,每次执行时,此函数都会执行类似的操作。呃哦:&#34;类似&#34;。无论这个函数的结果是什么,它都应该进入一个数组。对该函数的每次调用都是数组的一个元素。您可以清楚地看到使用&#34; num&#34;识别当前运行的函数中发生的任何事情。
您的功能中包含哪些数据?
copyOne在这里是一个麻烦制造者,是什么导致你的困惑。它试图一次完成所有事情,因此你无法清楚地思考何时使用数组和何时使用Object。人们会称它为上帝对象。这不是一个好的对象。
您对变量名的选择非常糟糕。 你选择超级通用名称,如&#34; mcX&#34;只是为了以后添加一个名称属性来描述它的真实含义。 但即便如此,对于任何&#34; Box2&#34;应该是。 选择名称,以便您可以轻松了解代码中的内容。 看起来您为此问题创建了此结构jsut的全部或部分,因此缺少有意义的名称。 我强烈建议你不要通过这样的组合项目来学习。但是来自现实世界。
因此,我将强加以下目标: mc1和mc1Text代表一个标题 mc2和mc2Text代表内容
有了这一切,我再问一遍:
您的功能中包含哪些数据?
标题和内容都包含一个框和一个文本。 这些是不同的东西,因此标题和内容都是具有属性的对象&#34; box&#34;和&#34;文字&#34; 人们可以认为,由于这种相似性,它们都应该进入阵列。 但我不同意。标题和文字不是一回事。您以不同方式处理字幕和文本。走在街上你可能很快就会在新闻中看到一个很大的标题,但不是冗长的文字。这就是为什么它们中的每一个都应该是在函数中创建的对象的属性。
这里有点结论:
var allBoxes:Array = []; // array to store the similar results of every function call
function createBoxes():void
{
var boxes:Object = {};
//the box consists of caption & content, both bying of the same type, but are containing different data
boxes.caption = {box:{}, text:{}}; //caption
boxes.content = {box:{}, text:{}}; //content
allBoxes.push(boxes);
}
就是这样。这就是我用对象和数组建模数据的方式和原因。
但它并没有在这里结束。我的结论缺少你发布的很多代码。 虽然上述内容主要与语言无关,但缺少的代码特定于Actionscript,而不仅仅是如何建模数据。它如下......
As3是面向对象的。 这很好,因为上面的结论中有很多对象。 要定义某个对象是如何/做/移动/放屁/等,可以创建类。
发生以下变化(出于本答案范围之外的原因):
createBoxes
(以前称为addBoxes)调用的构造函数
一个班级&#34; CaptionAndContent&#34;扩展了Sprite。caption
和content
将没有属性&#34;框&#34;,因为
他们可以成为自己的盒子。这正是它在这方面所做的
问题的代码。默认设置在其类的构造函数中设置。这里减少了代码片段,希望能够说明 类的外观。 每个类都应该在自己的文件中,包含必要的导入,包块以及您未在问题中指定的其他功能。
public class CaptionAndContent extends Sprite
{
private var caption:Caption;
private var content:Content;
public function CaptionAndContent(captionText:String = "", contentText:String = "")
{
caption = new Caption(captionText);
addChild(caption);
content = new Content(contentText);
content.y = caption.height;
addChild(content);
}
}
public class ClickableBoxWithText extends Sprite
{
protected var textField:TextField;
public function ClickableBoxWithText(text:String = "")
{
textField = new TextField();
textField.text = text;
addChild(textField);
addEventListener(MouseEvent.CLICK, onClick);
}
protected function onClick(mouseEvent:MouseEvent):void
{
//override this in a sublclass
}
}
public class Caption extends ClickableBoxWithText
{
public function Caption(text:String = "")
{
super(text);
// apply all the default settings of caption here.
}
}
public class Content extends ClickableBoxWithText
{
public function Content(text:String = "")
{
super(text);
// apply all the default settings of content here.
}
}
使用它们看起来像这样:
var allBoxes:Array = []; // array to store the similar results of every function call
function createBoxes():void
{
var captionAndContent:CaptionAndContent = new CaptionAndContent("This is the caption...", "...for this content");
captionAndContent.x = nextXpos;
addChild(captionAndContent);
allBoxes.push(captionAndContent);
}
最后但并非最不重要的是,点击处理程序中的识别问题。 您的问题已包含答案:
event.currentTarget
这是对点击对象的引用。 在我的代码中它将是
mouseEvent.currentTarget
这标识了已经的对象。查找其中一个属性(例如其名称)以查找该名称的所有对象,只是为了识别您必须识别的相同对象(没有名称)以便得到名字。
无论如何,您还无法通过名称识别对象。名称与所谓的独特之处有什么不同,最后是一个数字。正如在这个答案中指出的那样,这就是所谓的索引,你试图用它来识别它应该进入一个数组。在我的示例代码中,这是allBoxes
。