flex中绑定遇到的一个问题
现在要在项目中要实现界面上布局的更改,就像FlashIDE中那些面板,它能拖动与其他面板合并,也能单独出来接受用户交互。比如:项目中主程序有3个模块,分别是聊天,视频,用户列表,写了三个组件分别为Chat.MXML,Video.MXML,UserList.MXML,在主程序初始化后,Chat组件(模块)是镶嵌于主界面里假设主界面有一个HBox,即Chat是HBox的一个子对象,现在新的要求要在主程序初始化后Chat组件是一个浮动状态,可以拖动。将Chat组件变为浮动后,Chat组件中中用标签建立的绑定就会出问题,代码如下:
Chat.MXML---继承于Canvas,里面放了一个TextArea组件用于显示调试消息,一个标签建立的绑定,用于设置消息。
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300" creationComplete="init()">
<mx:Script>
<![CDATA[
import vo.MessageVo;
import model.BindingModel;
import mx.managers.PopUpManager;
import mx.core.Application;
import mx.containers.TitleWindow;
import mx.binding.utils.BindingUtils;
[Bindable]private var _text:String="";
private var _titleWindow:TitleWindow;
private var _count:int = 0;
private function init():void
{
trace("init");
}
[Bindable]
public function get message():MessageVo
{
return null;
}
public function set message(msgVo:MessageVo):void
{
_count++;
_text+=(_count+" : "+msgVo.msg+"\n");
}
/*
* 利用TitleWindow弹出Chat组件,使之处于浮动状态
**/
public function popWindow():void
{
trace(_titleWindow,"A");
if(!_titleWindow)_titleWindow = new TitleWindow();
_titleWindow.title = "Test";
_text+=("popuping..."+"\n");
trace(_titleWindow.contains(this),"B");
if(!_titleWindow.contains(this))
{
trace("C");
_titleWindow.addChild(this);
trace(this,"AAAA");
PopUpManager.addPopUp(_titleWindow,Application.application as DisplayObject);
}
_text+=("popuped!"+"\n");
}
]]>
</mx:Script>
<!--绑定到Chat的message属性-->
<mx:Binding source="BindingModel.getInstance().messageVo" destination="message"/>
<mx:TextArea x="40" y="10" height="182" width="320" id="ta" text="{_text}"/>
</mx:Canvas>
主界面BindingTest.MXML---主界面有两个状态,第一个状态放一个按钮,用于点击进入第二个状态。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:components="components.*"
creationComplete="init()" >
<mx:Script>
<![CDATA[
import vo.MessageVo;
import vo.PersonVo;
import model.BindingModel;
private function init():void
{
}
private function onClick():void
{
chat.popWindow();
}
/* 向Model中写入数据,显示在Chat组件中 */
private function setVo():void
{
var msg:MessageVo = new MessageVo();
msg.msg = new Date().time.toString();
BindingModel.getInstance().messageVo = msg;
}
/* 进入主状态 */
private function enterMain():void
{
this.currentState='main';
chat.popWindow();
}
private function chatInit():void
{
}
]]>
</mx:Script>
<mx:Button x="293" y="287" label="进入主界面" id="enterBtn" click="enterMain()" fontSize="12"/>
<mx:states>
<mx:State name="main">
<mx:AddChild position="lastChild">
<mx:VDividedBox width="100%" id="vbox" height="332">
<mx:TextInput id="ti" height="22"/>
<components:Chat id="chat" height="217" creationComplete="chatInit()"/>
</mx:VDividedBox>
</mx:AddChild>
<mx:AddChild position="lastChild">
<mx:Button x="83" y="340" label="弹出" id="btn" click="onClick()" fontSize="12"/>
</mx:AddChild>
<mx:AddChild position="lastChild">
<mx:Button x="10" y="340" label="发消息" id="setBtn" click="setVo()" fontSize="12"/>
</mx:AddChild>
<mx:RemoveChild target="{enterBtn}"/>
</mx:State>
</mx:states>
</mx:Application>
进入主界面后,Chat组件是嵌入在一个VDividedBox中的,除了Chat,VDividedBox里面还有一个TextInput,TextInput没有其他作用,只是放里面让VDividedBox显示分隔符。
下面是一个model,一个vo,代码如下:
package model
{
import vo.MessageVo;
import vo.PersonVo;
[Bindable]
public class BindingModel
{
private static var _instance:BindingModel;
public static function getInstance():BindingModel
{
if(_instance==null)
{
_instance = new BindingModel();
}
return _instance;
}
public function BindingModel()
{
}
public var personVo:PersonVo = new PersonVo();
public var messageVo:MessageVo = new MessageVo();
}
}
package vo
{
public class MessageVo
{
public var msg:String = "oh,yeah!";
public var time:Number;
public function MessageVo()
{
}
}
}
运行效果如下:
点击进入主界面后,你会发现在titleWindow中有两条输出,也就是说Chat组件的属性message被赋值了两次,而Chat中只有BindingModel.getInstance().messageVo是它的源,且问题不仅如此。进入主界面后,点击发消息按钮执行主界面上的setVo函数,改变BindingModel.getInstance().messageVo,继而设置了Chat组件的属性message,但一次设置,Chat中TextArea中居然会有两次输出...问题出在哪里?
从进入主界面的按钮来找,发现enterMain函数中在设置了主界面的状态为"main"后,立即调用Chat来弹出自己,设置浮动。问题就出在此处,因为此时Chat并没有初始化完成就完成了弹出(添加到显示列表),同时Chat中的标签建立的绑定将BindingModel.getInstance().messageVo与message绑定,而初始化后又一次将添加到显示列表,再次将BindingModel.getInstance().messageVo与message绑定,虽然这两个绑定的源和目的都是相同,但Flex却把它当成两个绑定,一旦设置BindingModel.getInstance().messageVo就会有两次赋值个message属性,即有两次输出。
解决办法:
下面的init函数为Chat的creationComplete事件处理函数。
1。可以将弹出Chat组件的方法延时调用,即可以监听Chat的creationComplete事件,在此事件的处理函数中执行chat.popWindow();
private function init():void
{
trace("init");
this.popWindow();
}
2。还是在进入主界面时弹出窗口,但要将Chat中标签建立的绑定改为As动态建立绑定,并且也得是在creationComplete处理函数中处理。
private function init():void
{
trace("init");
BindingUtils.bindProperty(this,"message",BindingModel.getInstance(),["messageVo"]);
}
E-mail:给我发邮件
出处:http://ywxgod.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号