2015-01-21 4 views
0

Я потратил почти 1 неделю на изучение работы с объектами вместо массивов. Я думал, что их легко вызвать, создать некоторые объекты и установить их свойства. Однако я не могу получить доступ к ним теперь, я попытался это:Использование объектов вместо массивов

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 
} 

Мой вопрос, если есть практический способ иметь дело с объектами, в противном случае то, что цель их использования.

Edit: Вот моя функция, которую я использую для создания MovieClips и другие вещи:

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()); 
} 

Я назвал эту функцию в цикле, так что я создал много MovieClips. Теперь я не могу получить доступ к свойствам объектов и их дочерним элементам (например, текстовому полю).

Объекты я на сцене: MovieClips и текстовые поля

Где они приходят из: выше

То, что я пытаюсь сделать с ними функции: Трассировка MovieClips и текстовые поля (которые holded объектами) изменить их дети (TextField) текст

Что происходит вместо того, что я ожидал: код трассировки выходов неопределенными вместо того чтобы дать мне тип объекта trace(getChildByName("copy_" + str)); // trying to trace an object by name

есть ли практический способ accessi ng объект, имя которого «copy_1», и его свойство, имя которого «box2_1» (movieclip)?

+0

Вопрос слишком общий и философский. Попробуйте перефразировать, что именно не работает для вас в этом фрагменте кода? Что вы ожидаете от этого и что вы получаете вместо этого? – evilpenguin

+0

Благодарим вас за ответ. Я редактировал вопрос. (вроде философского :)) – nikel

+0

Я не уверен, как этот вопрос относится к объектам/массивам и прослушивающим событиям для доступа к объектам отображения. Из вашего кода похоже, что вы пытаетесь получить доступ к части строки, чтобы получить MovieClip или что-то в этом роде, но отключить для меня это «Я потратил почти 1 неделю на изучение работы с объектами вместо массивов». –

ответ

1

Одна проблема, которую я вижу, - это объект «copyOne», созданный в рамках «addBoxes», поэтому он больше не будет существовать вне этой функции.

Другое, вы пытаетесь получить доступ к объекту через getChildByName, которое только обращается к displayObjects объекта displayObjectContainer, из которого вы звоните.

Если вы хотите свободно отслеживать переменные с помощью таких объектов, как объекты или MovieClips (которые являются объектами динамического стиля, которые позволяют добавлять к ним свойства по своему усмотрению), просто используйте MovieClips для размещения ваших значений. MovieClips, находясь на сцене, будет сохранен в памяти до удаления с displayList (stage).

Кроме того, ознакомьтесь с Словарем, своего рода ключом/ценностным способом хранения коллекций объектов.

Еще лучше, если вы используете строго типизированные пользовательские объекты (создаете свои собственные классы для расширения MC и добавляете свои собственные общедоступные или частные методы и значения), есть преимущества, такие как использование векторов (причудливые быстрые массивы, которые совместим с любым выбранным типом объекта).

+0

Благодарим вас за ответ. поэтому мне нужно изменить кодировку, научиться использовать пользовательские классы. – nikel

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'; 
}) 
0

Array and Object - это обе структуры данных. Данные означают некоторую информацию. Структура данных означает, что некоторая форма информации хранится определенным образом.

Array and Object - два разных способа хранения информации.

Массивы идентифицируют данные с целыми числами. Целое число, чтобы идентифицировать один элемент массива называется индекс

Массивы идеально подходят для представления списка подобных вещей, которые принадлежат друг к другу.

var names:Array = ["John", "Paul", "George", "Ringo"]; 

Это часто означает, что элементы массива имеют тот же тип, как и в приведенном выше примере. Но они не должны: «Каковы имена четырех Биттлз»

var numbers:Array = [42, "twenty-five", "XIIV"]; 

Для приведенных выше примеров это легко ответить на вопросы, «Какие различные представления чисел вы наткнуться во время вашего путешествие по историческому городу? ». Другие вопросы сложнее или невозможно ответить. «Какие римские цифры вы наткнулись на исторический город?»

Объекты идентифицируют данные с именами. имя для идентификации одного элемента объекта называется свойством

Объекты идеально подходят для представления списка непохожих вещей, которые принадлежат друг другу.

var paula:Object = {age:37, name:"Paula", hairColor:0x123456}; 

Это часто означает, что элементы объекта имеют различного типа, как и в приведенном выше примере. Но они не должны:

var car:Object = {manufacturer:"Porsche", color:"red", sound:"wroooooom", soundOfDriver:"weeeeeeeeeeee"}; 

Учитывая это, давайте взглянем на код и посмотреть, как он относится. Большая картинка: у вас есть функция addBoxes, которую вы вызываете несколько раз. Поскольку одна функция должна иметь одну цель, эта функция будет делать что-то подобное каждый раз, когда она будет выполнена. Uh-Oh: «похоже». Каким бы ни был результат этой функции, он должен попасть в массив. Каждый вызов этой функции будет элементом массива. Вы можете ясно это увидеть при использовании «num», чтобы определить, что происходит в вашем текущем запуске функции.

Какие данные имеются в вашей функции?

  • copyOne
  • mc1
  • mc1Text
  • mc2
  • mc2Text

copyOne является нарушителем здесь и что вызывает ваше замешательство. Он пытается сделать все сразу, и поэтому вы не можете четко мыслить, когда использовать массив и объект Object. Можно было бы назвать это божественным объектом. И это не очень хороший объект.

Ваш выбор для имен переменных очень плох. Вы выбираете супер общие имена, такие как «mcX», чтобы позже добавить к нему свойство имени, которое описывает, что это на самом деле. Но даже это не относится ни к какому «Box2». Выберите имена, чтобы было легко понять, что в вашем коде есть. Похоже, вы создали все или части этой структуры jsut для этого вопроса и поэтому не имели значимых имен. Я настоятельно рекомендую вам не изучать подобные проекты. Но из реального мира.

Я поэтому навязываю следующую цель: mc1 и mc1Text представляет собой заголовок mc2 и mc2Text представляет содержание

При всем этом, я снова спрашиваю:

Каких данных присутствуют в вашем функционировать?

  • captionBox
  • CaptionText
  • contentBox
  • contentText

И заголовок и содержание состоят из коробки и текста. Это разные вещи, поэтому заголовок и содержимое - это объект со свойствами «поле» и «текст». Можно подумать, что из-за этого сходства оба они должны войти в массив. Но я прошу отличить. Заголовок и текст - это не одно и то же. Вы имеете дело с подписями и текстами по-разному. Прогуливаясь по улицам, вы можете быстро получить большой заголовок в новостях, но не длинный текст. Вот почему каждый из них должен быть свойством объекта, созданного в функции.

Вот несколько из заключения:

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 - объект предназначенный. Это хорошо, потому что вышеприведенный вывод содержит много объектов. Чтобы определить, как работает какой-либо объект/делает/перемещает/farts/etc, создается класс.

следующие изменения происходят (по причинам выходит за рамки этого ответа):

  • createBoxes (ранее известный как addBoxes) вызывает конструктор класса «CaptionAndContent», который расширяет Sprite.
  • Нет необходимости явно создавать объекты «ящики», поскольку конструктор выполняет именно это.
  • caption и content не будут обладать "полем", потому что они могут быть самим ящиком. Это точно, как это делается в коде вопроса . Настройки по умолчанию задаются в конструкторах их классов.

Вот уменьшенный фрагмент кода, который мы надеемся, показывает, как классы мог выглядеть. Каждый класс должен быть в собственном файле с необходимым импортом, блоком пакетов и дополнительными функциями, которые вы не указали в своем вопросе.

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.