PDA

Просмотр полной версии : Как вызвать функцию класса из анонимной функции этого же класса?


Жень Шень
14.04.2008, 14:45
Привет!
Прошу срочной помощи!
Есть класс:
class ConnectorClass {
public var command:String;
public var args;
public function ConnectorClass() {
this.watch("globalflag", varWatcher);
}
public function varWatcher() {
switch (command) {
case "load_movie" :
loadPage(args);
break;
// другие case не показаны
}
}
private function loadPage(filename) {
var page_mclListener:Object = new Object();
page_mclListener.onLoadInit = function(target_mc:MovieClip) {
fmessage(filename);
};
var page_mc_loader:MovieClipLoader = new MovieClipLoader();
page_mc_loader.addListener(page_mclListener);
page_mc_loader.loadClip(filename, _root.page_mc);
}
public function fmessage(par:String) {
_root.falert(par);
}
}
public function fmessage(par:String) вызывает стандартный alert из _root. При обращении к ней из разных мест работает.
Как правильно вызвать ее из анонимной функции function(target_mc:MovieClip)?
Мне надо по окончании загрузки клипа сообщить об этом в алерт!!!
Спасибо.

udaaff
14.04.2008, 14:52
Нужно использовать Delegate, так как fmessage в анонимной функции function(target_mc:MovieClip) вызывается в области видимости page_mclListener.

iNils
14.04.2008, 14:55
Вот так
class ConnectorClass {
public var command:String;
public var args;
private var __filename:String
public function ConnectorClass() {
this.watch("globalflag", varWatcher);
}
public function varWatcher() {
switch (command) {
case "load_movie" :
loadPage(args);
break;
// другие case не показаны
}
}
private function loadPage(filename) {
__filename = filename;
var page_mc_loader:MovieClipLoader = new MovieClipLoader();
//// забудь про пустый объекты ради загрузки
page_mc_loader.addListener(this);
page_mc_loader.loadClip(filename, _root.page_mc);
}
public function fmessage(par:String) {
_root.falert(par);
}
private function onLoadInit (target_mc:MovieClip) {
fmessage(__filename);
}
}

Жень Шень
14.04.2008, 15:07
iNils, супер! Спасибо. Повторю чьи-то слова: "Ты, добрый фей!"

2udaaff. Если не трудно, хотел бы увидеть вариант с Делегатом. Я пытался прикрутить его, но....

iNils
14.04.2008, 15:21
Тут делегат не нужен, так как класс подписан на получения событий от page_mc_loader и область видимости указана правильно.

Жень Шень
17.04.2008, 14:20
Привет!
С успехом применил поправки к коду, но просил бы пролить свет по вопросу "листенерства". Локальным объектом var page_mc_loader был подписан собственно класс (this). Но, функцию loadPage я буду использовать сотни раз в единственном объекте этого класса. Так как я нигде не отписываюсь, не загрузиться ли память неудаленными листенерами, несмотря на лакальность page_mc_loader? И есль это так, где мне применять removeListener?
А также теоретический вопрос: можно ли узнать, есть ли, и сколько листенеров у определенного объекта?
Спасибо.

iNils
17.04.2008, 15:45
Тогда стоит page_mc_loader сделать свойством класса и вынести создание в конструктор.
А узнать количество подписчиков можно так
trace (page_mc_loader["_listeners"].length);

Жень Шень
17.04.2008, 16:34
Спасибо, iNils.
По первому вопросу так и поступлю. В принципе, думал так сделать, но имел надежду, что с локальной переменной умрет и подписка. Теперь сомненья прочь!
А "теоретический" вопрос возник из-за проблем в подгружаемом мувики - там создавался листенер. После перезагрузки нового мувика и создания такого же листенера встала проблема ссылки - старый объект был удален, но листенер держал его еще в памяти, отсюда сбой в работе. Теперь стало все ясно - откуда ноги росли.
Я тогда обошел эту проблему так:Key.removeListener(userKey);
_global.userKey = new Object();
_global выручил. Читал, что глобальные переменные "не есть хорошо". Интересно, можно ли после удаления объекта (в моем случае userKey) впоследствии удалить ссылку, чтоб не пользоваться _global?

Dr.OH
08.06.2008, 18:52
Немного продолжу тему таким вопросом - есть класс, примерно такой:

class MyClass {
function obj_move_process() {
trace('actions');
}

function obj_move() {
this.onMouseMove = this.caller.obj_move_process;
}

function obj_init(obj:MovieClip) {
obj.caller = this;
obj.onPress = this.obj_move;
}
}

Ве достаточно просто. Передаем указатель на MovieClip, в нем создаем переменную caller, которой присваиваем экземпляр класса. А затем просто вызываем функцию. Т.е. логически все верно, но скомпилировать этот код нельзя, т.к. Flash сообщает, что у свойства caller нет метода obj_move_process. Точно также вызывает ошибку и this.onMouseMove, т.к. у класса MyClass нет метода onMouseMove. Как от этого избавиться???

silin
08.06.2008, 23:04
Dr.OH, это уже другая тема, незачем постить в чужой топик
по вопросу:
у MyClass (если он наследник Object, а не MovieClip) нет onMouseMove и как следствие obj_move изначально провальный как метод MyClass
если нужно передать его obj.caller' у, то держать его надо в виде свойства как анонимную функцию:
class MyClass
{
var obj_move:Function = function()
{
this.onMouseMove = this.caller.obj_move_process;
}

function obj_move_process() {
trace('actions');
}

function obj_init(obj:MovieClip) {
obj.caller = this;
obj.onPress = obj_move;
}
}

ps: зачем такие выверты нужны не оч. понятно..

Dr.OH
08.06.2008, 23:40
Не работает :( Ошибка все та же - не определено this.onMouseMove.
Идея заключалась примерно в следующем - есть класс, описывающий какой-то элемент, например, меню... или что-то другое. А точнее базовое поведение этого меню (нажатие на кнопку, наведение курсора и т.п.) Сам класс при этом не содержит никакой UI - он просто описывает поведение. "Фишка" заключается в следующем: меню можно нарисовать как угодно, вообще все, что хочется, и просто передать необходимые объекты в качестве элементов инициализации класса, после чего меню резко начнёт работать. Возможно я не очень хорошо объяснил, но примерно как-то так.

Во, вроде бы что-то заработало - помогло dynamic совместно с resolve.