Просмотр полной версии : dynamic class create
Вообщем наступил на грабли...
требуется создать класс через его имя, откопал интересную доку:
http://www.gskinner.com/blog/archives/2003/12/class_locations.html
однако, пробую:
function getInstanceOf(p_fullName:String):Object
{
var classPath:Array = p_fullName.split(".");
var package:Object = _global;
var l = classPath.length-1;
for (var i:Number=0;i<l;i++)
{
package = package[classPath[i]];
}
var c:Function = package[classPath[classPath.length-1]];
var instance:Object = new c();
return instance;
}
var a = getInstanceOf("classes.map.layers.landscape");
trace (a);
stop();
на выходе идёт undefined, хотя класс существует...
не могу понять, в чём проблема...
помогите, pls
В моем случае(перед вызовом функции, создал экземпляр, для того чтобы класс импортировался) возвращает object Object, правда я вопроса не понял.
Попробуй удостовериться, что класс существует...потому что если класс не используеться, то он и не импортируеться во флэшку.
function getInstanceOf(p_fullName:String):Object
{
var classPath:Array = p_fullName.split(".");
var package:Object = _global;
var l = classPath.length-1;
for (var i:Number=0;i<l;i++)
{
package = package[classPath[i]];
trace(package)
}
var c:Function = package[classPath[classPath.length-1]];
var instance:Object = new c();
return instance;
}
var b:orange.utils.FPS = new orange.utils.FPS(20);
trace(getInstanceOf("orange.utils.FPS"));
import package.Class в данном случае не помогает.
если мы напишем
import mx.controls
и в test movie нажмем crtl+shift+v то получим
Level #0:
Variable _level0.$version = "WIN 7,0,19,0"
а если
import mx.controls.*
var a = new CheckBox();
то получаем
Global Variables:
Variable _global.mx = [object #1, class 'Object'] {
core:[object #2, class 'Object'] {
UIObject:[function 'symbolOwner'],
UIComponent:[function 'symbolOwner']
},
skins:[object #5, class 'Object'] {
SkinElement:[function 'SkinElement']
},
styles:[object #7, class 'Object'] {
CSSTextStyles:[function 'CSSTextStylesDependency'],
CSSStyleDeclaration:[function 'CSSStyleDeclaration'],
StyleManager:[function 'StyleManager']
},
controls:[object #11, class 'Object'] {
SimpleButton:[function 'symbolOwner'],
Button:[function 'symbolOwner'],
CheckBox:[function 'symbolOwner']
}
}
Level #0:
Variable _level0.$version = "WIN 7,0,19,0"
Variable _level0.a = [object #15] {}
хмм... а если нет возможности создать по экземпляру класса?
каким образом тогда можно это обойти?
как я уже сказал я не понял сути вопроса, тебе нужно создать в условиях AS1 класс написанный на AS2 ? если так то возможнсть уже присутствует(ибо тебе придеться выбрать в настройках AS2 для Flash 6 или 7) ...или я не догоняю?
причем тут в условиях ас1 классы ас2??? человек хочет иметь возможность по названию класса создать объект! это как раз чистый ас2
ну проблемы ты правильно указал, если нету явного упоминания класса, его и не будет в результируещем свф, так что либо в библиотеки создать пустые мувы, которые будут связаны с теми классами которые нужны или запихнуть в свф все нужные классы через мтаск - мне так кажется :)
в условиях AS2 создать AS2 class. Это просто пример функции, на самом деле всё это по классам пораспихано и из классов вызывается
если так то возможнсть уже присутствует(ибо тебе придеться выбрать в настройках AS2 для Flash 6 или 7)
малость не понял, что ты хотел сказать этой фразой?
потом импорт, это больше деректива к компилятору на сокращение пути к классу, тем более все это действует только в том кадре где импорт указан, естественно в данном случае не поможет....
так и думал, что придётся извращаться :(
спасибо за идею с mtasc
да и ещё один тупой вопрос из той-же серии....
как получить аргументы, передаваемые функции, достаточно просто и понятна (через arguments). А вот как эти аргументы потом передать конструктору класса в текущей функции?
то есть юзание
var a = getInstanceOf("classes.map.layers.landscape",val1,val2);
было-бы эквивалентно
var a = new classes.map.layers.landscape(val1,val2);
var a = getInstanceOf("classes.map.layers.landscape",val1,val2);
было-бы эквивалентно
var a = new classes.map.layers.landscape(val1,val2);
посмотри в хелпе Function.apply придеться чуть доработать, функцию getInstanceOf()
и всеже я до сих пор не врубаюсь, зачем все это, если можно написать new package.Class();
:) Nirth представь момент что ты заранее не знаешь что это будеть new x.a.s.Class1 или new x.a.s.Class2
:) через функшн.апли тоже не пройдет, не тот случай, я думаю тебе просто надо будет написать эквивалент оператора new
вообщем есть 10 - 20 принципиально разных классов, экземпляры которых описываются в xml и по описанию создаются. Причём хочется иметь возможность добавлять классы не изменяя того класса, в котором создаются экземпляры этих самых классов. Очень-уж неохота лезть в написаный код.
Таким образом будет достаточно написать класс, прицепить его с помощью mtasc к swf-ке и описать его экземпляры в xml, не затрагивая другие классы
Как вариант
/**
*
* @author Nirth
* @version 0.0.2
*/
class orange.utils.Importer
{
/**
* imports classes to the SWF
* @usage orange.utils.Importer.doImport(package1.Class1,package2.Class2 etc);
* @return nothing
*/
public static function doImport ():Void
{
orange.utils.Importer.__getFields (arguments);
}
private static function __getFields (args : Array) : Array
{
var result : Array = new Array ();
for (var item : String in args)
{
//trace(args[item]);
for (var field : String in args [item])
{
result.push (args [item][field]);
//break;
}
}
return result;
}
}
В классе есть лишний метод, это я себе оставил маневр для апгрейда, вообще все можно сократить до одного
Nirth представь момент что ты заранее не знаешь что это будеть new x.a.s.Class1 или new x.a.s.Class2
Сделаю класс прокси, который будет решать что создавать.
с аргуентами решил не заморачиваться, а передавать всё в одном object конструктору, а он уже сам разберёться :)
Сделаю класс прокси, который будет решать что создавать.
ну тогда не надо синтаксиса this ['a' + 'b'] создадим функцию прокси, которая будет решать что создавать
вот именно, а откуда this['a'+'b'] ?
Как вариант
/**
*
* @author Nirth
* @version 0.0.2
*/
class orange.utils.Importer
{
/**
* imports classes to the SWF
* @usage orange.utils.doImport(package1.Class1,package2.Class2 etc);
* @return nothing
*/
public static function doImport ():Void
{
orange.utils.Importer.__getFields (arguments);
}
private static function __getFields (args : Array) : Array
{
var result : Array = new Array ();
for (var item : String in args)
{
//trace(args[item]);
for (var field : String in args [item])
{
result.push (args [item][field]);
//break;
}
}
return result;
}
}
В классе есть лишний метод, это я себе оставил маневр для апгрейда, вообще все можно сократить до одного
импортировать типа такого?
orange.utils.doImport (package1.Class1,package2.Class2);
или так?
orange.utils.doImport ('package1.Class1','package2.Class2');
orange.utils.Importer.doImport(package1.Class1) и тд.
извиняюсь сделал ошибку в коментариях сейчас подправлю.
Объясни мне тупому тогда как именно твой класс импортирует?
З.Ы. попробуй создать пустой файл фла, в нем единственную строчку
mx.events.EventDispatcher и посмотри через дебагер импортировался ли класс mx.events.EventDispatcher?
В первом кадре пишем
orange.utils.Importer.doImport(mx.controls.CheckBox,mx.controls.DataGrid);
тестируем мувик, и смотрим переменные
Global Variables:
Variable _global.mx = [object #1, class 'Object'] {
core:[object #2, class 'Object'] {
UIObject:[function 'symbolOwner'],
UIComponent:[function 'symbolOwner'],
View:[function 'ViewDependency'] {
prototype:[object #6] {
loadExternal:[function 'loadExternal'],
prepareToLoadMovie:[function 'prepareToLoadMovie'],
waitForUnload:[function 'waitForUnload'],
checkLoadProgress:[function 'checkLoadProgress'],
contentLoaded:[function 'contentLoaded']
}
},
ExternalContent:[function 'ExternalContent'],
ScrollView:[function 'symbolOwner']
},
skins:[object #14, class 'Object'] {
SkinElement:[function 'SkinElement'],
Border:[function 'symbolOwner'],
RectBorder:[function 'symbolOwner'],
CustomBorder:[function 'symbolOwner']
},
styles:[object #19, class 'Object'] {
CSSTextStyles:[function 'CSSTextStylesDependency'],
CSSStyleDeclaration:[function 'CSSStyleDeclaration'],
StyleManager:[function 'StyleManager']
},
controls:[object #23, class 'Object'] {
SimpleButton:[function 'symbolOwner'],
Button:[function 'symbolOwner'],
CheckBox:[function 'symbolOwner'],
scrollClasses:[object #27, class 'Object'] {
ScrollBar:[function 'ScrollBar'],
ScrollThumb:[function 'ScrollThumb']
},
listclasses:[object #30, class 'Object'] {
DataSelector:[function 'DataSelector'],
DataProvider:[function 'DataProvider'],
ScrollSelectList:[function 'ScrollSelectList'],
SelectableRow:[function 'SelectableRow']
},
List:[function 'symbolOwner'],
DataGrid:[function 'symbolOwner'],
gridclasses:[object #37, class 'Object'] {
DataGridColumn:[function 'DataGridColumn'],
DataGridRow:[function 'DataGridRow']
},
TextInput:[function 'symbolOwner']
},
managers:[object #41, class 'Object'] {
DepthManager:[function 'DepthManager']
},
events:[object #43, class 'Object'] {
EventDispatcher:[function 'evtDipatcher'],
UIEventDispatcher:[function 'UIEventDispatcher']
},
effects:[object #46, class 'Object'] {
Tween:[function 'Tween']
}
}
Variable _global.orange = [object #48, class 'Object'] {
utils:[object #49, class 'Object'] {
Importer:[function 'Importer']
}
}
Level #0:
Variable _level0.$version = "WIN 7,0,19,0"
Movie Clip: Target="_level0.reserved"
с EventDispatcherom такая же история.
еще раз: случай без твоего класса:
попробуй создать пустой файл фла, в нем единственную строчку
mx.events.EventDispatcher и посмотри через дебагер импортировался ли класс mx.events.EventDispatcher?
это баг, который возможно устранят. если ты посмотришь в код EventDispatcher'a то заметишь там такую строчку new EventDispatcher - без скобок, тоесть на данный момент, это работает, но по идее класс импортироваться не должен(а в друг у меня просто в глобале такие объекты есть?) так что если макромедия пофиксит данную фичу думаю такой вариант работать не будет
ИМХО.
твой класс без данного бага в той форме как ты написал работать не будет!!!
потому что без данного бага твой метод доИмпорт получит лишь undefined
потом это это не баг, импорт классов происходит лишь после того как в глобале не оказалось соответствующих функций конструкторов
мда и в правду, намудрил, можно извратиться и вызывать методы конечно, но тогда есть опасность что вызовем чего нить плохого, или ненужного
args [item][field]();
это баг, который возможно устранят. если ты посмотришь в код EventDispatcher'a то заметишь там такую строчку new EventDispatcher - без скобок, тоесть на данный момент, это работает, но по идее класс импортироваться не должен(а в друг у меня просто в глобале такие объекты есть?) так что если макромедия пофиксит данную фичу думаю такой вариант работать не будет
ИМХО.
по поводу new EventDispatcher:
f = function () {
this.walla = 'walla';
}
a = new f;
trace ('>>> ' + a.walla);
посмотри трайс
это баг, который возможно устранят. если ты посмотришь в код EventDispatcher'a то заметишь там такую строчку new EventDispatcher - без скобок, тоесть на данный момент, это работает, но по идее класс импортироваться не должен(а в друг у меня просто в глобале такие объекты есть?) так что если макромедия пофиксит данную фичу думаю такой вариант работать не будет
ИМХО.
Ты что, шутишь? =)
f = function () {
this.walla = 'walla';
trace(this.walla);
}
new f;
f = function () {
this.walla = 'walla';
trace(this.walla);
}
new f;
и что ты этим хотел сказать?
То что на данный момент, флэш по левому обрабатывает конструктор, и скорее всего это исправиться(очень на это надеюсь)
а что ты хотел сказать этим?
f = function () {
this.walla = 'walla';
}
a = new f;
trace ('>>> ' + a.walla);
То что на данный момент, флэш по левому обрабатывает конструктор, и скорее всего это исправиться(очень на это надеюсь)
а что ты хотел сказать этим?
f = function () {
this.walla = 'walla';
}
a = new f;
trace ('>>> ' + a.walla);
слушайте хватит гнать на флэш, а? а как должен обрабатывать оператор new??? что должен создаваться экземпляр класса а конструктор класс не запускаться при new f?
в C# выдает ошибку если не поставить скобок, я поспрашивал пару программистов на C++ те тоже говорят что без скобок должна выдаваться ошибка, я не гоню.
я констатирую факт, что на данный момент AS слегонца багнутый :)
так же прикол в том, что private почему то работает как protected
в C# выдает ошибку если не поставить скобок, я поспрашивал пару программистов на C++ те тоже говорят что без скобок должна выдаваться ошибка, я не гоню.
я констатирую факт, что на данный момент AS слегонца багнутый :)
так же прикол в том, что private почему то работает как protected
Дарагой, ты только что узнал что AS это не C ? =) Поздравляю с открытием.
нуран почитай пожалуйста спецификацию emca которую юзает флэш, а потом уже хохми.
нуран почитай пожалуйста спецификацию emca которую юзает флэш, а потом уже хохми.
Иди сам читай, и ищи кучу отличий.
нуран почитай пожалуйста спецификацию emca которую юзает флэш, а потом уже хохми.
Вот может в Flash 8 приблизят ещё больше к спецификации, но сейчас то бессмысленно (почти =) на неё ссылаться.
да, сорри, что-то резко выражаюсь =\
Ткни ка пальцем, что то я не вижу чтоб не в ecma 262 не в ECMAScript 4 Draft Proposal, строчки где сказанно что объекты можно создавать юзая new но без скобок...
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.