Flex 下拉列表绑定问题(或错误?)
我在我的 Flex 项目中使用 MVC 模型。
我想要的是将值对象的类属性绑定到视图 mxml,然后通过更改值对象来更改该视图。
会发生什么:
- 将所选值设置为“c” - 索引 2
- 在“c”之前添加“x,y,z,”
- 按 Enter 键 ->现在索引 5
- 按回车键 ->现在索引是-1
- 请参见4。
为什么只有第一次更新有效?我知道我可能错过了一些明显的东西......
编辑: 运行示例
(PS 第一篇文章,我不确定如何打开 MXML 突出显示)
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="created(event)"
width="160" height="220">
<fx:Script>
<![CDATA[
import mx.collections.ArrayList;
import mx.events.FlexEvent;
import spark.events.IndexChangeEvent;
//===================================
// Pretend Value Object Class
[Bindable] private var list:ArrayList = null;
[Bindable] private var index:int = 0;
//===================================
protected function created(event:FlexEvent):void {
ddValues.addEventListener(FlexEvent.ENTER, update);
update();
}
private function update(... args):void {
//note selected item
trace("dropdown index: " + dd.selectedIndex);
var s:String = dd.selectedItem as String;
trace("selected item: " + s);
//build new list from csv
list = new ArrayList(ddValues.text.split(","));
trace("new list: " + ddValues.text);
trace("selected item: " + s);
//if exists in new list, set value object index
var newIndex:int = 0;
if(list)
list.toArray().forEach(function(ss:String, i:int, a:Array):void {
if(s == ss) newIndex = i;;
});
index = newIndex;
trace("new index: " + index + " (dropdown index: " + dd.selectedIndex + ")");
trace("===");
}
protected function ddChange(event:IndexChangeEvent):void
{
trace("selected item: " + (dd.selectedItem as String) + " (dropdown index: " + dd.selectedIndex + ")");
trace("===");
}
]]>
</fx:Script>
<s:Panel width="100%" height="100%" title="Drop Down Bug">
<s:layout>
<s:VerticalLayout gap="10" paddingLeft="10" paddingTop="10" paddingRight="10" paddingBottom="10"/>
</s:layout>
<s:DropDownList id="dd" dataProvider="{list}" selectedIndex="@{index}" change="ddChange(event)"></s:DropDownList>
<s:Label text="Label: {dd.selectedItem as String}" paddingTop="5" paddingBottom="5"/>
<s:Label text="Code Index: {index}" paddingTop="5" paddingBottom="5"/>
<s:Label text="DropDown Index: {dd.selectedIndex}" paddingTop="5" paddingBottom="5"/>
<s:TextInput id="ddValues" text="a,b,c,d,e"/>
</s:Panel>
</s:Application>
这是输出 编辑代码并添加痕迹。这是显示我的问题的输出:
dropdown index: -1
selected item: null
new list: a,b,c,d,e
selected item: null
new index: 0 (dropdown index: 0)
===
selected item: c (dropdown index: 2)
===
dropdown index: 2
selected item: c
new list: a,b,x,y,z,c,d,e
selected item: c
new index: 5 (dropdown index: 5)
===
dropdown index: 5
selected item: c
new list: a,b,x,y,z,c,d,e
selected item: c
new index: 5 (dropdown index: 5)
===
dropdown index: -1
selected item: null
new list: a,b,x,y,z,c,d,e
selected item: null
new index: 0 (dropdown index: 0)
===
I'm using the MVC model in my flex project.
What I'd like is to bind a value object's class properties to a view mxml, then change that view by altering the value object.
What happens:
- Set the selected value to 'c' - index 2
- Add 'x,y,z,' before 'c'
- Hit enter -> now index 5
- Hit enter -> now index is -1
- See 4.
Why does only the first update work ? I know I'm probably missing something obvious...
Edit: Running Example
(P.S. first post and im not sure how to turn on MXML highlighting)
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="created(event)"
width="160" height="220">
<fx:Script>
<![CDATA[
import mx.collections.ArrayList;
import mx.events.FlexEvent;
import spark.events.IndexChangeEvent;
//===================================
// Pretend Value Object Class
[Bindable] private var list:ArrayList = null;
[Bindable] private var index:int = 0;
//===================================
protected function created(event:FlexEvent):void {
ddValues.addEventListener(FlexEvent.ENTER, update);
update();
}
private function update(... args):void {
//note selected item
trace("dropdown index: " + dd.selectedIndex);
var s:String = dd.selectedItem as String;
trace("selected item: " + s);
//build new list from csv
list = new ArrayList(ddValues.text.split(","));
trace("new list: " + ddValues.text);
trace("selected item: " + s);
//if exists in new list, set value object index
var newIndex:int = 0;
if(list)
list.toArray().forEach(function(ss:String, i:int, a:Array):void {
if(s == ss) newIndex = i;;
});
index = newIndex;
trace("new index: " + index + " (dropdown index: " + dd.selectedIndex + ")");
trace("===");
}
protected function ddChange(event:IndexChangeEvent):void
{
trace("selected item: " + (dd.selectedItem as String) + " (dropdown index: " + dd.selectedIndex + ")");
trace("===");
}
]]>
</fx:Script>
<s:Panel width="100%" height="100%" title="Drop Down Bug">
<s:layout>
<s:VerticalLayout gap="10" paddingLeft="10" paddingTop="10" paddingRight="10" paddingBottom="10"/>
</s:layout>
<s:DropDownList id="dd" dataProvider="{list}" selectedIndex="@{index}" change="ddChange(event)"></s:DropDownList>
<s:Label text="Label: {dd.selectedItem as String}" paddingTop="5" paddingBottom="5"/>
<s:Label text="Code Index: {index}" paddingTop="5" paddingBottom="5"/>
<s:Label text="DropDown Index: {dd.selectedIndex}" paddingTop="5" paddingBottom="5"/>
<s:TextInput id="ddValues" text="a,b,c,d,e"/>
</s:Panel>
</s:Application>
And heres the output
Edited code and added traces. Heres the output that shows my problem:
dropdown index: -1
selected item: null
new list: a,b,c,d,e
selected item: null
new index: 0 (dropdown index: 0)
===
selected item: c (dropdown index: 2)
===
dropdown index: 2
selected item: c
new list: a,b,x,y,z,c,d,e
selected item: c
new index: 5 (dropdown index: 5)
===
dropdown index: 5
selected item: c
new list: a,b,x,y,z,c,d,e
selected item: c
new index: 5 (dropdown index: 5)
===
dropdown index: -1
selected item: null
new list: a,b,x,y,z,c,d,e
selected item: null
new index: 0 (dropdown index: 0)
===
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
哦,我明白现在发生了什么事。当您替换整个列表时,所选项目将为空,因为所选项目位于旧列表中。您需要在选择时存储所选项目,然后与该存储的项目(而不是当前选定的(空)项目)进行比较。
请注意,您所做的绝不是 MVC,除非您将 MVC 重新定义为“模型、视图和控制器都是同一件事”。在 MVC 中,模型不知道视图,并且视图只能访问模型中显示数据所需的部分。它没有对模型的写入访问权限。这就是控制器的功能。
Oh, I see what's going on now. When you replace the whole list, the selected item will be null, because the item that was selected was in the old list. You'll need to store the selected item when it is selected, and then do the comparison against that stored item, not the current selected (null) item.
Note that what you're doing is in no way MVC, unless you've redefined MVC to mean "Model, View, and Controller are all the same thing." In MVC, the model has no idea of the view, and the view only has access to read as much of the model as it needs to to display the data. It does not have write access to the model. That is the function of the controller.