PDA

Просмотр полной версии : ComboBox и Alert


JaLav
30.01.2007, 01:24
Хочу, чтоб, когда выбираю первый элемент Комбобокса, появлялось окошко Алерт с кнопкой ОК.
Почему выдает ошибку типа "безконечная рекурсия"?

import mx.controls.Alert;
var cbListener:Object = new Object();
combo.addItem ({label:"none", data:0});
combo.addItem ({label:"a", data:1});
cbListener.change = function(event_obj:Object)
{
var ob=event_obj.target.selectedItem.data;
if(ob==0)
{
Alert.show("...must be >0","Warning", Alert.OK);
}
};
combo.addEventListener("change", cbListener);

CorC
30.01.2007, 10:27
не поверите, вставил, все работает...
и ошибок тут не нахожу...

Nirth
30.01.2007, 10:28
чертовщина какая то, если вызвать Alert из обработчика событий получается глюк.

import mx.controls.Alert;
import mx.controls.ComboBox;

var interval:Number;

function onComboBoxChange(event:Object):Void
{
var target:ComboBox = ComboBox(event.target);

if(!Number(target.selectedItem.data))
{
interval = setInterval(showWarning, 1);
}
}

function showWarning():Void
{
Alert.show("Data is not big enough", "Warning");
clearInterval(interval);
}

comboBox.addItem({label:"Hello", data:0});
comboBox.addItem({label:"World", data:1});
comboBox.addEventListener("change", onComboBoxChange);

Не очень опрятно, но работает...

Nirth
30.01.2007, 10:31
Corc какая версия флэша у тебя?

У меня восьмерка, компилю под восьмерку.

CorC
30.01.2007, 10:35
а ну я пробовал под МХ запустить,
восьмерка есь но щаз МХ открыт :)

да в 8 мне вот такую загогулину выдало:
"Failed to create a new alert, probably because there is no Alert in the Library"
хотя он там есть :)

Nirth
30.01.2007, 10:37
наверное в восьмерке они компоненты решили пропатчить, и добавили багов.

etc
30.01.2007, 11:36
Почему бы не залезть внутрь компонентов и посмотреть?

Nirth
30.01.2007, 12:14
Почему бы не залезть внутрь компонентов и посмотреть?
Типа проанализировать код, локализовать ошибку, написатьзаплатку?

только когда мне заплатят=)

etc
30.01.2007, 13:44
Не, зачем, просто проанализировать и узнать, откуда она. А секрет продавать :D

Nirth
30.01.2007, 14:15
Кстати глюк присутствует только в ComboBox.

я попробывал Button, List они работают нормально.

Ошибка должно быть в этом методе.


//mx.controls.ComboBox
function _changeHandler(obj) : Void
{
var o = this.owner; // 'this' is the dropdown; 'o' is the combobox
var prevValue = o.selectedIndex;
obj.target = o;

if (this == this.owner.text_mc)
{
o.selectedIndex = undefined;
o.dispatchChangeEvent(obj,-1,-2); // Force a change event to be dispatched
}
else
{
// This assignment will also assign the label to the text field. See setSelectedIndex().
o.selectedIndex = selectedIndex;
// If this was generated by the dropdown as a result of a keystroke, it is
// likely a Page-Up or Page-Down, or Arrow-Up or Arrow-Down. If the selection
// changes due to a keystroke, we leave the dropdown displayed. If it changes
// as a result of a mouse selection, we close the dropdown.
if (!o._showingDropdown)
{
o.dispatchChangeEvent(obj,prevValue, o.selectedIndex);
} else if (!o.bInKeyDown) {
o.displayDropdown(false);
//o.dispatchChangeEvent(obj,-1, o.selectedIndex);

}
}
//o.dispatchEvent(obj);
}


или тут


function dispatchChangeEvent(obj,prevValue,newValue)
{
var eventObj:Object;
//trace(obj.type + " " + prevValue + " " + newValue);
if (prevValue != newValue)
{
if (obj != undefined && obj.type == "change")
{
eventObj = obj;
}
else
{
eventObj = {type:"change"};
}

//eventObj.prevValue = prevValue;
//eventObj.newValue = newValue;

dispatchEvent(eventObj);
}

}

копатся дальше пока лень.

JaLav
30.01.2007, 14:18
А как в код залезть? В МХ при добавлении компонента на панель Library добавляется папка Flash UI Components,
а в 8-м - нет. Flash8/en/configuration/сomponents те, что с разширением .swc?
В чем их надо открывать?

Nirth
30.01.2007, 14:24
классы компонентов лежат в
Flash 8/en/Configuration/Classes/mx

ComboBox соответсвенно в

Flash 8/en/Configuration/Classes/mx/controls/ComboBox.as

для более полной картины скажу что ComboBox наследует ComboBase, тот UIComponent а тот UIObject. и активно использует mx.controls.List.

JaLav
30.01.2007, 14:32
Спасибочки.

JaLav
30.01.2007, 16:06
Снова вопрос.
Если все это (рабочий пример Nirth-а)поставить в обработчик для кнопки

but.onRelease=function()
{
import mx.controls.Alert;
import mx.controls.ComboBox;
_global.leng=new Array();
var interval:Number;

onComboBoxChange=function(event:Object):Void
{
var target:ComboBox = ComboBox(event.target);
var ob=event.target.selectedItem.data;
leng[j]=ob;
trace(ob);
if(!Number(target.selectedItem.data))
{
comboBox.removeAll();
interval = setInterval(showWarning, 1);
}
}

function showWarning():Void
{
Alert.show("Data is not big enough", "Warning");
clearInterval(interval);
}
comboBox.addItem({label:"Hello", data:0});
comboBox.addItem({label:"World", data:1});
comboBox.addEventListener("change", onComboBoxChange);
}

при первом щелчке - все нормально, при втором данные выводятся дважды и т.д.
В том примере, который я писала вначале тоже была та же проблема.
Я поставила строчку

var cbListener:Object = new Object();

перед обработчиком кнопки.
А с примером, Nirth-а так не получается.
:)

Nirth
30.01.2007, 16:15
Я не понял ничего.

вообще зачем вставлять код в кнопку?...

Nirth
30.01.2007, 16:15
Вообще мой код, это Workaround к именно этому багу именно у ComboBox, кнопким такое делать не нужно.

JaLav
30.01.2007, 16:33
Просто у меня есть меню, динамическое. В зависимости от нажатого пункта меню в comboBox загружаются разные данные.
Пример с кнопкой - это для простоты.

Nirth
30.01.2007, 16:59
нечто вроде этого?

import mx.controls.Alert;
import mx.controls.Button;
import mx.controls.ComboBox;

var dp1:Array = [{label:"First Hello", data:0},
{label:"First Bye", data:1}];
var dp2:Array = [{label:"Second Hello", data:0},
{label:"Second Bye", data:1}];
var dp3:Array = [{label:"Third Hello", data:0},
{label:"Third Bye", data:1}];
var dataProviders:Array = new Array(dp1, dp2, dp3);

var comboBox:ComboBox;

function onButtonClick(event:Object):Void
{
var button:Button = Button(event.target);
comboBox.dataProvider = dataProviders[button.getDepth()-1];
}

function onComboChange(event:Object):Void
{
var cb:ComboBox = ComboBox(event.target);

if(!Boolean(cb.selectedItem.data))
{
setTimeout(Alert.show, 1,
"Data is not big enough", "Warning", Alert.OK);
}
}

function createApplication():Void
{
for(var i:Number = 1; i <= dataProviders.length; i++)
{
var btn:Button = createClassObject(mx.controls.Button,
String("btn"+i), i);
btn.move(0, (i-1)*btn.height);
btn.label = String("Button "+i);

btn.addEventListener("click", onButtonClick);
}

comboBox = createClassObject(ComboBox, "comboBox", getNextHighestDepth());
comboBox.move(200, 0);
comboBox.addEventListener("change", onComboChange);
}

createApplication();

CorC
30.01.2007, 17:04
а вы не пробовали после нажатия на кнопку очищать комбо?
или перед запонлением его?
а не после выбора компонента

JaLav
30.01.2007, 17:15
Вроде этого. И когда выбираешь первый пункт списка, должно появляться предупреждение.

JaLav
30.01.2007, 17:20
Да, комбо очищается после нажатия на кнопку(извините за некорректный пример). Тогда в комбо все нормально.
Но трейс выводит лишнее при повторном нажатии на кнопку. Или если кнопок много, то при нажатии
на ту, которая нажата позже

Nirth
30.01.2007, 17:25
У меня нету RAR

JaLav
30.01.2007, 17:27
Извините, плз., что морочу голову.
Разбираюсь с Вашым примером.
Я сначало не поняла, что там все работает.

silin
30.01.2007, 17:28
вообще-то у них для этих случаев doLater припасен:
import mx.controls.Alert;
var cbListener:Object = new Object();
combo.addItem({label:"none", data:0});
combo.addItem({label:"a", data:1});
cbListener.change = function(event_obj:Object) {
var cb=event_obj.target
var ob = cb.selectedItem.data;
if (ob == 0) {
cb.doLater(this,"alert");
}
};
cbListener.alert=function(){
Alert.show("...must be >0", "Warning", Alert.OK);
}
combo.addEventListener("change", cbListener);

CorC
30.01.2007, 17:37
класс, спасиб, выручили с doLater :)

Nirth
30.01.2007, 17:45
А вообще кто нибудь может мне объяснить, зачем создавать для листенера отдельный объект ?

etc
30.01.2007, 17:47
У народа, благодаря хелпу, возникло стойкое ощущение, что листенер — это какой-то определенный тип объекта, нестандартный.

silin
30.01.2007, 17:55
А вообще кто нибудь может мне объяснить, зачем создавать для листенера отдельный объект ?
можно и не создавать
import mx.controls.Alert;
combo.addItem({label:"none", data:0});
combo.addItem({label:"a", data:1});
combo.alert=function(){
Alert.show("...must be >0", "Warning", Alert.OK);
}
function change(event_obj:Object) {
var cb=event_obj.target
var ob = cb.selectedItem.data;
if (ob == 0) {
cb.doLater(this,"alert");
}
};
combo.addEventListener("change", change);
обычно и не надо, но в этом раскладе чтоб вызвать doLater приходится этот alert вешать на сам компонент, я этого делать не стал, потому как придет _etc (ой сори, уже пришел..) и скажет, что это не по-нашему, не по-бразильски..

Nirth
30.01.2007, 18:03
А да, забыл о особеностях doLater.

Кстати
[14:19] 7thsky.ru (Talk.v104AC80F35E): привет
[14:19] furzahad: привет
[14:20] 7thsky.ru:кстати насчет комбобокса и алерта, виснет там invalidate, я думаю проблема в том что дропдаун и алерт открываются через попапмэнэджер
[14:21] 7thsky.ru:то есть зависон происходит на методе дро в алерте, почему хрен его знает, я с дебаггером потестил

JaLav
30.01.2007, 18:05
Огромнейшее спасибо всем. Очень помогли.
:)