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"]);
   }

 

转载于:https://www.cnblogs.com/ywxgod/archive/2010/04/16/1713905.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值