Repository: flex-sdk Updated Branches: refs/heads/develop 9e3619cd9 -> c23af10fd
FLEX-35375 CAUSE: DataGrids didn't dispatch a VALUE_COMMIT event when a new dataProvider cleared the selection, thus allowing the selectedItem, selectedIndex, selectedItems, selectedIndexes to become null without a notification. Which also means that if there was any binding set up for any of those variables, it won't be triggered. SOLUTION: we now dispatch a VALUE_COMMIT event when a new dataProvider ends up clearing the selection. NOTE: also added a unit test for this bug, which fails without the fix and passes with the above fix. Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/c23af10f Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/c23af10f Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/c23af10f Branch: refs/heads/develop Commit: c23af10fdef366ad0a6c240b7b3b7e54ad308a67 Parents: 9e3619c Author: Mihai Chira <[email protected]> Authored: Mon Jan 22 11:22:18 2018 +0100 Committer: Mihai Chira <[email protected]> Committed: Mon Jan 22 11:22:18 2018 +0100 ---------------------------------------------------------------------- .../projects/spark/src/spark/components/Grid.as | 9 +- .../spark/components/Grid_FLEX_35375_Tests.as | 110 +++++++++++++++++++ .../spark/components/_ListWithMXMLBinding.mxml | 37 +++---- 3 files changed, 134 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/c23af10f/frameworks/projects/spark/src/spark/components/Grid.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/spark/src/spark/components/Grid.as b/frameworks/projects/spark/src/spark/components/Grid.as index 5f9f0cd..0df0884 100644 --- a/frameworks/projects/spark/src/spark/components/Grid.as +++ b/frameworks/projects/spark/src/spark/components/Grid.as @@ -2452,7 +2452,7 @@ public class Grid extends Group implements IDataGridElement, IDataProviderEnhanc clearSelection(); else setSelectedIndex(rowIndex); - } + }; deferredOperations.push(f); // function f() to be called by commitProperties() invalidateProperties(); } @@ -4515,14 +4515,14 @@ public class Grid extends Group implements IDataGridElement, IDataProviderEnhanc if (dataProviderChanged || columnsChanged) { - + var selectionChanged:Boolean = false; // Remove the current selection and, if requireSelection, make // sure the selection is reset to row 0 or cell 0,0. if (gridSelection) { var savedRequireSelection:Boolean = gridSelection.requireSelection; gridSelection.requireSelection = false; - gridSelection.removeAll(); + selectionChanged = gridSelection.removeAll(); gridSelection.requireSelection = savedRequireSelection; } @@ -4543,6 +4543,9 @@ public class Grid extends Group implements IDataGridElement, IDataProviderEnhanc if (!anchorChanged) initializeAnchorPosition(); + if(selectionChanged) + dispatchFlexEvent(FlexEvent.VALUE_COMMIT); + dataProviderChanged = false; columnsChanged = false; } http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/c23af10f/frameworks/projects/spark/tests/spark/components/Grid_FLEX_35375_Tests.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/spark/tests/spark/components/Grid_FLEX_35375_Tests.as b/frameworks/projects/spark/tests/spark/components/Grid_FLEX_35375_Tests.as new file mode 100644 index 0000000..2d3e871 --- /dev/null +++ b/frameworks/projects/spark/tests/spark/components/Grid_FLEX_35375_Tests.as @@ -0,0 +1,110 @@ +package spark.components { + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.events.KeyboardEvent; + import flash.ui.Keyboard; + + import mx.binding.utils.BindingUtils; + + import mx.collections.ArrayCollection; + + import mx.collections.IList; + + import org.flexunit.asserts.assertTrue; + import org.flexunit.async.Async; + import org.fluint.uiImpersonation.UIImpersonator; + + public class Grid_FLEX_35375_Tests { + private var _sut:DataGrid; + private static const NO_ENTER_FRAMES_TO_ALLOW:int = 2; + private static var noEnterFramesRemaining:int = NaN; + private static const _finishNotifier:EventDispatcher = new EventDispatcher(); + private var _initialSelectedItem:Object = null; + private var _selectedItemBindingTriggered:Boolean; + + [Before] + public function setUp():void + { + _sut = new DataGrid(); + } + + [After] + public function tearDown():void + { + _sut = null; + _initialSelectedItem = null; + _selectedItemBindingTriggered = false; + UIImpersonator.removeAllChildren(); + } + + [Test(async, timeout=2000)] + public function test_changing_dataProvider_clears_selection_and_notifies_bindings():void + { + //given + _sut.requireSelection = false; + _sut.dataProvider = getTestDataProvider(); + UIImpersonator.addChild(_sut); + + noEnterFramesRemaining = NO_ENTER_FRAMES_TO_ALLOW; + UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame); + Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_reset_data_provider, 600); + } + + private function then_reset_data_provider(event:Event, passThroughData:Object):void + { + //given + _sut.selectedItem = _sut.dataProvider.getItemAt(0); + _initialSelectedItem = _sut.selectedItem; + BindingUtils.bindSetter(setNewlySelectedItem, _sut, "selectedItem"); + + //when + _sut.dataProvider = getTestDataProvider(); + + //then + noEnterFramesRemaining = NO_ENTER_FRAMES_TO_ALLOW; + UIImpersonator.testDisplay.addEventListener(Event.ENTER_FRAME, onEnterFrame); + Async.handleEvent(this, _finishNotifier, Event.COMPLETE, then_verify_notifications_sent_if_selection_cleared, 600); + } + + private function then_verify_notifications_sent_if_selection_cleared(event:Event, passThroughData:Object):void + { + //given + const selectedItemNotificationsShouldHaveBeenSent:Boolean = _sut.selectedItem != _initialSelectedItem; + + //then + if(selectedItemNotificationsShouldHaveBeenSent) + { + assertTrue("The change of the selectedItem should have been notified by the Grid!", _selectedItemBindingTriggered); + } + else + { + assertTrue(true); //nothing to verify + } + } + + + + + private function setNewlySelectedItem(value:Object):void + { + if(value != _initialSelectedItem) + { + _selectedItemBindingTriggered = true; + } + } + + private static function getTestDataProvider():IList + { + return new ArrayCollection([{id:1, name:"Andy"}, {id:2, name:"Zainab"}, {id:3, name:"Greta"}]); + } + + private static function onEnterFrame(event:Event):void + { + if(!--noEnterFramesRemaining) + { + UIImpersonator.testDisplay.removeEventListener(Event.ENTER_FRAME, onEnterFrame); + _finishNotifier.dispatchEvent(new Event(Event.COMPLETE)); + } + } + } +} http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/c23af10f/frameworks/projects/spark/tests/spark/components/_ListWithMXMLBinding.mxml ---------------------------------------------------------------------- diff --git a/frameworks/projects/spark/tests/spark/components/_ListWithMXMLBinding.mxml b/frameworks/projects/spark/tests/spark/components/_ListWithMXMLBinding.mxml index f2b24fb..778350d 100644 --- a/frameworks/projects/spark/tests/spark/components/_ListWithMXMLBinding.mxml +++ b/frameworks/projects/spark/tests/spark/components/_ListWithMXMLBinding.mxml @@ -1,23 +1,22 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//////////////////////////////////////////////////////////////////////////////// - <?xml version="1.0"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> <s:List xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" selectedItem="@{container.selectedCompany.headquarter}" dataProvider="{container.potentialHeadquarters}">
