最近要用flex实现权限管理军火库装配,记下来吧,流失得太多了。
主要是角色应该拥有的资源,spring security 3.x里面需要的,角色列表,某角色拥有的资源,资源树checkbox的操作。
代码如下:
treecheckbox
CheckTreeRenderer
package com.gwtjs.renderer.tree
{
import flash.events.MouseEvent;
import flash.xml.*;
import mx.collections.*;
import mx.controls.CheckBox;
import mx.controls.Image;
import mx.controls.Tree;
import mx.controls.listClasses.*;
import mx.controls.treeClasses.*;
public class CheckTreeRenderer extends TreeItemRenderer
{
protected var myImage:Image;
private var imageWidth:Number = 6;
private var imageHeight:Number = 6;
private var inner:String ;
protected var myCheckBox:CheckBox;
static private var STATE_SCHRODINGER:String = "schrodinger";
static private var STATE_CHECKED:String = "checked";
static private var STATE_UNCHECKED:String = "unchecked";
public function CheckTreeRenderer ()
{
super();
mouseEnabled = false;
}
override protected function createChildren():void
{
super.createChildren();
myCheckBox = new CheckBox();
myCheckBox.setStyle( "verticalAlign", "middle" );
myCheckBox.addEventListener( MouseEvent.CLICK, checkBoxToggleHandler );
addChild(myCheckBox);
myImage = new Image();
myImage.source = inner;
myImage.addEventListener( MouseEvent.CLICK, imageToggleHandler );
myImage.setStyle( "verticalAlign", "middle" );
addChild(myImage);
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if(super.data)
{
if (super.icon != null)
{
myCheckBox.x = super.icon.x;
myCheckBox.y = super.icon.y;
myCheckBox.width = super.icon.width;
myCheckBox.height = super.icon.height;
super.icon.x = myCheckBox.x + myCheckBox.width ;
super.label.x = super.icon.x + super.icon.width;
}
else
{
myCheckBox.x = super.label.x;
myCheckBox.y = super.label.y;
myCheckBox.height = super.label.height;
super.label.x = myCheckBox.x + myCheckBox.width + myCheckBox.height;
}
if (data.@state == STATE_SCHRODINGER)
{
myImage.x = myCheckBox.x + 4;
myImage.y = myCheckBox.y + 4;
myImage.width = imageWidth;
myImage.height = imageHeight;
}
else
{
myImage.x = 0;
myImage.y = 0;
myImage.width = 0;
myImage.height = 0;
}
}
}
override public function set data(value:Object):void
{
super.data = value;
setCheckState (myCheckBox, value, value.@state);
if(TreeListData(super.listData).item.@type == 'dimension')
{
setStyle("fontStyle", 'italic');
}
else
{
if (this.parent != null)
{
var _tree:Tree = Tree(this.parent.parent);
_tree.setStyle("defaultLeafIcon", null);
}
setStyle("fontStyle", 'normal');
}
}
private function toggleParents (item:Object, tree:Tree, state:String):void
{
if (item == null)
{
return;
}
else
{
item.@state = state;
toggleParents(tree.getParentItem(item), tree, getState (tree, tree.getParentItem(item)));
}
}
private function toggleChildren (item:Object, tree:Tree, state:String):void
{
if (item == null)
{
return;
}
else
{
item.@state = state;
var treeData:ITreeDataDescriptor = tree.dataDescriptor;
if (treeData.hasChildren(item))
{
var children:ICollectionView = treeData.getChildren (item);
var cursor:IViewCursor = children.createCursor();
while (!cursor.afterLast)
{
toggleChildren(cursor.current, tree, state);
cursor.moveNext();
}
}
}
}
private function getState(tree:Tree, parent:Object):String
{
// Alert.show("1");
var noChecks:int = 0;
var noCats:int = 0;
var noUnChecks:int = 0;
if (parent != null)
{
var treeData:ITreeDataDescriptor = tree.dataDescriptor;
var cursor:IViewCursor = treeData.getChildren(parent).createCursor();
while (!cursor.afterLast)
{
if (cursor.current.@state == STATE_CHECKED)
{
noChecks++;
}
else if (cursor.current.@state == STATE_UNCHECKED)
{
noUnChecks++
}
else
{
noCats++;
}
cursor.moveNext();
}
}
if ((noChecks > 0 && noUnChecks > 0) || (noCats > 0))
{
return STATE_SCHRODINGER;
}
else if (noChecks > 0)
{
return STATE_CHECKED;
}
else
{
return STATE_UNCHECKED;
}
}
private function imageToggleHandler(event:MouseEvent):void
{
myCheckBox.selected = !myCheckBox.selected;
checkBoxToggleHandler(event);
}
private function checkBoxToggleHandler(event:MouseEvent):void
{
if (data)
{
var myListData:TreeListData = TreeListData(this.listData);
var selectedNode:Object = myListData.item;
var tree:Tree = Tree(myListData.owner);
var toggle:Boolean = myCheckBox.selected;
if (toggle)
{
toggleChildren(data, tree, STATE_CHECKED);
}
else
{
toggleChildren(data, tree, STATE_UNCHECKED);
}
var parent:Object = tree.getParentItem (data);
toggleParents (parent, tree, getState (tree, parent));
tree.parent.dispatchEvent(new TreeCheckBoxEvent(TreeCheckBoxEvent.CHECKBOX_CLICK,false,false,data));
}
}
private function setCheckState (checkBox:CheckBox, value:Object, state:String):void
{
if (state == STATE_CHECKED)
{
checkBox.selected = true;
}
else if (state == STATE_UNCHECKED)
{
checkBox.selected = false;
}
else if (state == STATE_SCHRODINGER)
{
checkBox.selected = false;
}
}
}
}
TreeCheckBoxEvent
package com.gwtjs.renderer.tree
{
import flash.events.Event;
public class TreeCheckBoxEvent extends Event
{
public static const CHECKBOX_CLICK:String = "checkBoxClick";
private var _data:Object;
public function get data():Object{
return this._data;
}
public function set data(data:Object):void{
this._data = data;
}
public function TreeCheckBoxEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false,data:Object=null)
{
if(data != null) this._data = data;
super(type, bubbles, cancelable);
}
}
}
RoleEditorWindow.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
width="470" height="440" close="PopUpManager.removePopUp(this)" layout="vertical"
creationComplete="creationCompleteHandler(event)"
showCloseButton="true" title="角色编辑{action}">
<mx:Script>
<![CDATA[
import com.gwtjs.renderer.tree.TreeCheckBoxEvent;
import mx.collections.ArrayCollection;
import mx.collections.XMLListCollection;
import mx.controls.Alert;
import mx.events.CloseEvent;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
[Bindable]
public var action:String = "Insert";
[Bindable]
public var role:Object = new Object();
[Bindable]
public var treeData:ArrayCollection = new ArrayCollection();
[Bindable]
public var folderList:XMLList =
<>
<folder id="1" state="unchecked" resourceName="Marketing Collateral" isBranch="true" >
<folder id="2" state="unchecked" isBranch="true" resourceName="Media, PR, and Communications" >
<folder id="3" state="unchecked" isBranch="false" resourceName="Talking Points" />
<folder id="4" state="unchecked" isBranch="false" resourceName="Rep Points" />
<folder id="5" state="unchecked" isBranch="false" resourceName="Special Updates" />
<folder id="6" state="unchecked" isBranch="false" resourceName="White Papers" />
</folder>
<folder id="7" state="unchecked" isBranch="true" resourceName="Forms and Applications" >
<folder id="8" state="unchecked" isBranch="false" resourceName="Applications" />
<folder id="9" state="unchecked" isBranch="false" resourceName="Forms" />
</folder>
</folder>
</>;
[Bindable]
public var folderCollection:XMLListCollection;
//保存数据
protected function saveNode(event:MouseEvent):void
{
saveBtn.enabled = false;
if("Update"==action){
}else{
}
//取树勾选的项
getTreeCheckboxState(folderList);
Alert.show(getResouceToString());
PopUpManager.removePopUp(this);
}
//重置表单
protected function resetNode(event:MouseEvent):void
{
if("Update"==action){
}else{
}
}
//遍历tree的数据,如果某用户拥有角色标识,应该勾选上。
public function isExists(str:String,trees:XMLList):void{
//trace(str);
//Alert.show(trees.toString()+":"+str,"Test");
for each(var t:XML in trees){
//Alert.show(t.@id+":"+str,"期待"+str+"出现");
if(t.@id.toString()==str){
t.@state = "checked";//勾选上
}
if (t.hasComplexContent()){
arguments.callee(str,t.children());//递归找下去,不能错过一个。
}
}
}
protected function creationCompleteHandler(event:FlexEvent):void
{
Alert.show(action);
if("Update"==action){
//遍历数据打上拥有标记
var ids:Array = role.resource.split(",");
for(var i:int=0;i<ids.length;i++){
var str:String = ids[i];
isExists(str,folderList);
}
}
//Alert.show(folderList.toString()+"","Test");
//监听checkbox点击事件
this.addEventListener(TreeCheckBoxEvent.CHECKBOX_CLICK,treeCheckBoxHandler);
folderCollection = new XMLListCollection(folderList);
checkTree.dataProvider = folderCollection;//树给数据
}
//点击后应该做的事
private function treeCheckBoxHandler(event:TreeCheckBoxEvent):void{
var tempXml:XML = event.data as XML;
//Alert.show(tempXml.toXMLString(),"");
}
//更新datagrid,这里没用。
private function updataDataGrid():void{
//Alert.show(checkTree.selectedItem.@resourceName,checkTree.selectedItem.@state);
}
//返回字符串
public function getTreeCheckboxState(trees:XMLList):void{
//trace(str);
//Alert.show(trees.toString()+":"+str,"Test");
for each(var t:XML in trees){
//Alert.show(t.@id+":"+str,"期待"+str+"出现");
if(t.@state == "checked"){
var obj:Object = new Object();
obj.resourceId = t.@id;
obj.resourceName = t.@resourceName;
treeData.addItem(obj);
}
if (t.hasComplexContent()){
arguments.callee(t.children());//递归找下去,不能错过一个。
}
}
}
//返回字符串
public function getResouceToString():String{
var reso:String = "[";
for each(var obj:Object in treeData){
reso+="{resoueceId:"+obj.resourceId;
reso+=",resourceName:'"+obj.resourceName+"'},";
}
reso=reso.substring(0,reso.length-1);
reso+="]";
return reso;
}
]]>
</mx:Script>
<mx:Form width="100%">
<mx:FormItem label="角色名称" width="100%">
<mx:TextInput width="100%" id="roleName" text="{role.roleName}"/>
</mx:FormItem>
<mx:FormItem label="" width="100%">
<mx:HBox width="100%">
<mx:CheckBox label="系统角色" id="issys" selected="{role.issys}"/>
<mx:CheckBox label="起用" id="byEnabled" selected="{role.enable}"/>
</mx:HBox>
</mx:FormItem>
<mx:FormItem label="说明" width="100%">
<mx:TextArea width="100%" id="roleDesc" text="{role.roleDesc}"/>
</mx:FormItem>
</mx:Form>
<mx:Form width="100%">
<mx:Tree
id="checkTree"
itemRenderer="com.gwtjs.renderer.tree.CheckTreeRenderer"
itemClick="updataDataGrid()"
labelField="@resourceName"
width="100%" height="100%" >
</mx:Tree>
</mx:Form>
<mx:HBox width="100%" height="36">
<mx:HBox width="100%" />
<mx:Button label="保存" click="saveNode(event)" id="saveBtn"/>
<mx:Button label="重置" click="resetNode(event)"/>
<mx:HBox width="100%" />
</mx:HBox>
</mx:TitleWindow>
测试文件SysRoleManagerTest.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12" creationComplete="creationCompleteHandler(event)" minWidth="955" minHeight="600" xmlns:control="com.gwtjs.control.*">
<mx:Script>
<![CDATA[
import com.gwtjs.components.RoleEditorWindow;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.events.CloseEvent;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
private var pageIndex:int=0;
private var pageSize:int=5;
[Bindable]
public var roleArray:ArrayCollection = new ArrayCollection([
{id:1,roleName:'系统超级管理员',roleDesc:"管理系统",issys:true,enable:true,resource:""},
{id:2,roleName:'系统管理员',roleDesc:"管理系统",issys:true,enable:true,resource:""},
{id:3,roleName:'编辑1',roleDesc:"营销策划者",issys:false,enable:true,resource:"1,2,3,7,8"},
{id:4,roleName:'系统超级管理员',roleDesc:"管理系统",issys:true,enable:true},
{id:5,roleName:'系统管理员',roleDesc:"管理系统",issys:true,enable:true},
{id:6,roleName:'编辑2',roleDesc:"营销策划者",issys:false,enable:true,resource:"1,2,3,7,8"},
{id:7,roleName:'系统超级管理员',roleDesc:"管理系统",issys:true,enable:true},
{id:8,roleName:'系统管理员',roleDesc:"管理系统",issys:true,enable:true},
{id:9,roleName:'编辑3',roleDesc:"营销策划者",issys:false,enable:true,resource:"1,2,3,7,8"},
{id:10,roleName:'系统超级管理员',roleDesc:"管理系统",issys:true,enable:true},
{id:11,roleName:'系统管理员',roleDesc:"管理系统",issys:true,enable:true},
{id:12,roleName:'编辑4',roleDesc:"营销策划者",issys:false,enable:true,resource:"1,2,3,7,8"}
]);
protected function creationCompleteHandler(event:FlexEvent):void
{
serverPagingBar1.dataGrid=roleAdg;
serverPagingBar1.pagingFunction=pagingFunction;
}
private function pagingFunction(pageIndex:int,pageSize:int):void{
//new StorageFactory().getOrderPaged(onResult,pageIndex,pageSize);
}
protected function addHandler(event:MouseEvent):void
{
var editWin:RoleEditorWindow = new RoleEditorWindow();
editWin.action = "Insert";
editWin.title = "新增角色";
PopUpManager.addPopUp(editWin,this,true);
PopUpManager.centerPopUp(editWin);
}
protected function updateHandler(event:MouseEvent):void
{
var editWin:RoleEditorWindow = new RoleEditorWindow();
editWin.role = roleAdg.selectedItem;
editWin.action = "Update";
editWin.title = "编辑角色";
PopUpManager.addPopUp(editWin,this,true);
PopUpManager.centerPopUp(editWin);
}
protected function removeHandler(event:MouseEvent):void
{
var item:Object = roleAdg.selectedItem;
Alert.show("确定删除["+item.roleName+"] ?","信息提示",(1|2),this,function(event:CloseEvent):void{
if(event.detail == Alert.YES){
for(var i:int=0;i<roleArray.length;i++){
if(item.roleName==roleArray[i].roleName){
roleArray.removeItemAt(i);
}
}
}
});
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:HBox width="100%">
<mx:LinkButton label="添加角色" click="addHandler(event)"/>
<mx:LinkButton label="修改角色" click="updateHandler(event)"/>
<mx:LinkButton label="删除角色" click="removeHandler(event)"/>
</mx:HBox>
<mx:DataGrid id="roleAdg" width="100%" height="100%" dataProvider="{roleArray}"
variableRowHeight="true">
<mx:columns>
<mx:DataGridColumn dataField="roleName" headerText="角色名称"/>
<mx:DataGridColumn dataField="roleDesc" headerText="角色说明"/>
<mx:DataGridColumn dataField="issys" headerText="系统角色"/>
<mx:DataGridColumn dataField="enable" headerText="起用"/>
<mx:DataGridColumn headerText="编辑"/>
</mx:columns>
</mx:DataGrid>
<control:PagingBar id="serverPagingBar1" height="36" width="100%" paddingTop="6"/>
</mx:VBox>
</mx:Application>