Почему ярлыки таинственным образом исчезают из ComboBox в Flex 3? - PullRequest
2 голосов
/ 16 апреля 2010

Обратите внимание на программу Flex ниже (я использую Flex Builder 3 с 3,5 SDK). Второй выпадающий список условен для первого. Если выбрано «имя», вы можете выбрать «фамилию». Если выбрано «none», вам не разрешено выбирать фамилию, а вам предлагается выбрать имя.

Чтобы увидеть таинственную проблему исчезающих ярлыков, запустите эту программу и выберите имя. Затем выберите фамилию. Все хорошо. Затем выберите «нет» в первом поле со списком. Приглашение второго комбинированного списка изменяется обратно, а фамилии удаляются. Все еще хорошо. Затем попробуйте выбрать имя и фамилию еще раз. Вы увидите, что после выбора имени фамилии не появляются, хотя пробелы для них появляются (и если вы отлаживаете программу, в поставщике данных появляются правильные данные).

Эта «ошибка» убивала меня изнутри весь день. Проект, в котором я реализую это поведение, немного сложнее, но этот пример в основном иллюстрирует происходящее. Это ошибка во Flex или я что-то не так делаю?

Спасибо!

<?xml version="1.0" encoding="utf-8"?>

<mx:Script>
    <![CDATA[
        import mx.collections.ArrayCollection;

        [Bindable]
        public var cbCompanyDP:ArrayCollection = new ArrayCollection( [ { firstName: "None", data: 0 },
                                                                        { firstName: "Bob", data: 1 },
                                                                        { firstName: "Bart", data: 2 } ] );

        [Bindable]
        public var cbEmployeeDP:ArrayCollection = new ArrayCollection();

        public var employees:ArrayCollection = new ArrayCollection( [ { lastName: "Smith" },
                                                                      { lastName: "Smyth" },
                                                                      { lastName: "Smick" },
                                                                      { lastName: "Smack" } ] );

        [Bindable]
        public var prompt:String = "Choose First Name first";

        public function cbFirstNameChange( value:int ):void
        {
            if ( value == 0 )
            {
                employees.removeAll();
                setEmpDP( employees );
                prompt = "Choose First Name first";
            }
            else
            {
                setEmployees();
                setEmpDP( employees );
                prompt = "Now choose Last Name";
            }
        }

        private function setEmpDP( ac:ArrayCollection ):void
        {
            cbEmployeeDP = ac;
        }

        private function setEmployees():void
        {
            employees = new ArrayCollection( [ { lastName: "Smith" },
                                               { lastName: "Smyth" },
                                               { lastName: "Smick" },
                                               { lastName: "Smack" } ] );
        }
    ]]>
</mx:Script>

<mx:HBox>

    <mx:ComboBox dataProvider="{cbCompanyDP}"
        id="cbFirstName"
        labelField="firstName"
        width="200"
        change="cbFirstNameChange(cbFirstName.selectedItem.data)"
        prompt="Choose a first Name" />

    <mx:ComboBox dataProvider="{cbEmployeeDP}"
        id="cbLastName"
        labelField="lastName"
        width="200"
        prompt="{prompt}" />
</mx:HBox>

Ответы [ 5 ]

2 голосов
/ 04 ноября 2010

Проблема в том, что отсутствует привязка. Если вы измените dataProvider ComboBox, он не изменит dataProvider сгенерированного выпадающего списка. Таким образом, окно знает новый список, но выпадающий список все еще обрабатывает старый. Чтобы это исправить, вы должны создать подкласс ComboBox и переопределить set dataProvider и получить dataProvider (для симметрии).

override protected function set dataProvider (value:Object):void {
  super.dataProvider=value;
  if(dropdown != null)
    super.dropdown.dataProvider=value;
}

Для обновления ширины раскрывающегося списка в случае изменения ширины ComboBox также необходимо переопределить другую функцию:

override protected function updateDisplayList
    ( unscaledWidth:Number, unscaledHeight:Number ):void {
  super.updateDisplayList (unscaledWidth, unscaledHeight);
  if (dropdown != null)
    dropdown.width = unscaledWidth;
}

Таким образом, все работает как надо. если вы хотите, вы можете в set dunction проверить, равен ли selectedIndex -1 (что в редактируемом поле означает, что есть введенный вручную контент), сохранить его из super.text и восстановить его в super.text (и установить индекс на -1 снова), как только вы установили новый dataProvider. В противном случае текст в поле ввода будет потерян или заменен первым элементом списка.

2 голосов
/ 20 июля 2010

не устанавливайте новую коллекцию ArrayCollection в dataProvider в Flex 3.5, если поставщик данных уже установлен - установите dataProvider.source (чтобы не создавать новую ссылку)

1 голос
/ 02 сентября 2010

У меня была такая же проблема только вчера. Кажется, это ошибка в 3.5. Это происходит, когда вы назначаете новый объект ArrayCollection объекту, связанному в выпадающем списке. Если щелкнуть в поле со списком, он обновится и покажет реальный контент.

Решение этой проблемы в 3.5: не назначать новую коллекцию массивов для связанной переменной. Вы должны только установить источник, как сказал anton, или использовать методы add / remove / addAll Item. Примерно так же должно работать:

private function setEmpDP( ac:ArrayCollection ):void
    {

        cbEmployeeDp.removeAll();
        cbEmployeeDP.addAll(ac);
    }
0 голосов
/ 20 апреля 2010

Ну, похоже, есть два ответа: Да, это ошибка в Flex 3.5 SDK, поскольку она не возникает в 4 (я не тестировал с другими SDK). Однако, так как я не могу изменить SDK в середине проекта, обходной путь появился в другом вопросе: Flex 3.5.0; Обновление списка отображения ComboBox при изменении поставщика данных

Спасибо всем за участие.

0 голосов
/ 16 апреля 2010

Я пробовал с другим SDK (3.2 и 4), и он работает, поэтому я думаю, что это ошибка от 3.5

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...