Почему установщик dataprovider не вызывается после фильтрации arraycollection с использованием функции filter

#apache-flex #actionscript-3 #flex3

#apache-flex #actionscript-3 #flex3

Вопрос:

Я использую это:

 private var _hrInfoView:ArrayCollection;
 [Bindable]
 public function get HRInfoView():ArrayCollection
  {
   return _hrInfoView;
   }
  public function set HRInfoView(value:ArrayCollection):void
  {
   _hrInfoView = value;
  }

 private function onFilterByContent(event:ContextMenuEvent):void
 {              
    HRInfoView.filterFunction = processFilter;  
    HRInfoView.refresh();
  //Break point here shows HRInfoView as different what is in line above. Why is setter not called?
}
  

Когда я ставлю точку останова на установщик HRInfoView, он никогда не попадает (когда я могу четко видеть в выражении watch, что HRInfoView изменился до и после фильтрации)! Почему?
Спасибо.

Комментарии:

1. Неужели некому ответить? Спасибо.

Ответ №1:

РЕДАКТИРОВАТЬ: После повторного прочтения вопроса, я думаю, что вижу вашу проблему.

Когда вы применяете функцию фильтра к ArrayCollection, вы фактически не влияете на ArrayCollection. Flex создает копию ArrayCollection и помещает ее в «оболочку» и включает только записи, соответствующие вашему фильтру. Вот почему ваш установщик никогда не вызывается.

Если вы вызываете ArrayCollection.длина в отфильтрованной коллекции будет отображаться количество отфильтрованных записей вместо общего количества записей, с которых вы начали. Если вы удалите функцию filter и вызовете метод refresh(), эта коллекция-оболочка будет удалена.

Вам не нужно делать ничего особенного, чтобы получить эту копию-оболочку ArrayCollection. Flex автоматически возвращает отфильтрованную копию коллекции всякий раз, когда вы используете исходную ArrayCollection.

Эта ссылка содержит некоторую дополнительную информацию.

Комментарии:

1. Пробовал это. Все та же проблема.

2. Более важным вопросом должно быть, что на самом деле делает функция filter? Вероятно, это вообще не изменяет dataprovider! Не могли бы вы дать мне некоторое представление об этом? Спасибо.

3. @user Можете ли вы опубликовать код, в котором вы привязываете ArrayCollection к вашей сетке данных?

4. @user Функция filterFunction используется для фильтрации коллекции массивов, чтобы показывать только элементы, соответствующие определенным критериям. Как только вы примените функцию filter к вашему ArrayCollection и вызовете метод refresh(), он удалит все строки, которые не соответствуют вашему фильтру. Проверьте brandonellis.org/?p=69 для краткого примера.

5. Спасибо, Джейсон, я это уже знал… Что мне нужно было знать, так это то, как на самом деле работает filterfunction… когда вы говорите, что это устраняет, как это делается? Потому что я вижу, что установщик не вызывается даже после фильтрации, и мне нужно знать причину такого поведения… еще раз спасибо… Я собираюсь опубликовать полный код в ближайшее время…

Ответ №2:

перейдите сюда и прочитайте исходный код

[ПРАВИТЬ]

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

        [Bindable]
        public var myAC:ArrayCollection = new ArrayCollection([{label:"One"}, {label:"Two"}, {label:"Three"}, {label:"Four"}]);

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

        public function removeFilter(e:Event):void{
            trace(this.myAC.source.length )
            this.myAC.filterFunction = null;
            this.myAC.refresh()
            trace(this.myAC.source.length )
        }
        public function addFilter(e:Event):void{
            trace(this.myAC.source.length )
            this.myAC.filterFunction = filterFunc;
            this.myAC.refresh()
            trace(this.myAC.source.length )
        }
        public function filterFunc( item:Object ):Boolean{
            if( item.label == "One" )
                return true;

            if( item.label == "Two" )
                return true;

            return false;
        }
        public function copyData(e:Event):void{
            myAC2 =   new ArrayCollection( myAC.toArray() );  
            myAC2.refresh()
        }
    ]]> 
</mx:Script>
<mx:Label text="original data with filter option"  y="0"/>
<mx:DataGrid y="26" id="nameGrid" dataProvider="{myAC}" width="200" height="200"/>
<mx:Button id="button2" label="Add Filter" click="addFilter(event)" x="0" y="234"/>
<mx:Button id="button3" y="264" label="Remove Filter" click="removeFilter(event)"/>


<mx:Button id="button4" x="289" y="234" label="copy filtered data" click="copyData(event)"/>
<mx:Label text="Copied filtered data"  x="300" y="0"/>
<mx:DataGrid  y="26" x="287" id="nameGrid2" dataProvider="{myAC2}" width="200" height="200"/>
  

Комментарии:

1. эта ссылка хороша только для уровня приложения… Мне нужно было знать, как на самом деле работает filterfunction… когда вы говорите, что это устраняет, как это делается? Потому что я вижу, что установщик не вызывается даже после фильтрации, и мне нужно знать причину такого поведения…

2. функции фильтра не вызывают и не устанавливают данные, они работают, проверяя каждый элемент в arraycollection и возвращая true или false. Я вскоре опубликую пример функции

3. Хорошо, я добавил образец для вас, создайте новый проект и попробуйте это

4. Мне жаль, Том, но я предполагаю, что вы полностью неверно истолковали мой вопрос. Я не спрашиваю об этом. Я знаю, как это очень хорошо использовать. И я также знаю эту функциональность. Если вы еще раз проследите за вопросом и приведенными выше комментариями между мной и Джейсоном, вы узнаете, в чем здесь проблема. В любом случае, спасибо.

5. Чего не понять, я ответил на все, что вы спросили в моем примере. Я также добавил функцию удаления фильтра. Исходные данные никогда не исчезают, они просто отфильтрованы. Просто удалите функцию фильтра, и у вас есть данные.

Ответ №3:

Это не вызывает установщик, потому что вы не устанавливаете это свойство. Что вы делаете, так это вызываете получатель, чтобы вы могли получить от него свойство для установки этого. Оба HRInfoView.filterFunction и HRInfoView.refresh() вызывают средство получения для получения _hrInfoView , а затем вызывают функции или свойства из этого.