惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Visual Studio Blog
大猫的无限游戏
大猫的无限游戏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
腾讯CDC
S
Securelist
Know Your Adversary
Know Your Adversary
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
博客园 - 【当耐特】
V2EX - 技术
V2EX - 技术
J
Java Code Geeks
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
Cisco Talos Blog
Cisco Talos Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
阮一峰的网络日志
阮一峰的网络日志
美团技术团队
W
WeLiveSecurity
S
SegmentFault 最新的问题
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
宝玉的分享
宝玉的分享
博客园 - Franky
S
Security Affairs
博客园 - 司徒正美
V
V2EX
K
Kaspersky official blog
T
Threatpost
NISL@THU
NISL@THU
博客园 - 叶小钗
Help Net Security
Help Net Security
PCI Perspectives
PCI Perspectives
IT之家
IT之家
小众软件
小众软件
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Last Week in AI
Last Week in AI
Jina AI
Jina AI
爱范儿
爱范儿
罗磊的独立博客
N
News and Events Feed by Topic
博客园 - 三生石上(FineUI控件)
有赞技术团队
有赞技术团队
P
Proofpoint News Feed
L
LINUX DO - 热门话题
Google Online Security Blog
Google Online Security Blog
雷峰网
雷峰网
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint

博客园 - jiekengxu

工厂方法模式(Factory Method Pattern) 生成器模式(Builder) 抽象工厂模式(Abstract Factory Pattern) 中小型项目的权限管理的数据关系图 简陋的会计凭证金额输入控件(再加强) Web Services Enhancements 3.0 Quick Start(四) 初识HTC asp.net 2.0 缓存(页面输出缓存) asp.net 2.0 缓存(理论篇) 智能客户端概述 Web Services Enhancements 3.0 Quick Start(三) 简陋的会计凭证金额输入控件(加强) Web Services Enhancements 3.0 Quick Start(二) 简陋的会计凭证金额输入控件 Web Services Enhancements 3.0 Quick Start(一) 利用AJAX.net设计现在执行运算的报表 单件模式在报表中的使用 Web Service Software Factory 构架 Web Service Software Factory 入门
asp.net 2.0 权限树的控制(多处转载)
jiekengxu · 2006-11-19 · via 博客园 - jiekengxu

            做权限的时候,主要实现如下功能
            1、该节点可以访问,则他的父节点也必能访问;
     2、该节点可以访问,则他的子节点也都能访问;
     3、该节点不可访问,则他的子节点也不能访问。
         使用带CheckBox的数型结构能得到很好的用户体验,可是编程的难度也是有点增加,如果全部有服务端来完成,那点下刷下,肯定不行,只能使用javascript,javascript调试的时候郁闷的很,一个字类,还有郁闷的递归,麻烦
我以前是使用以下该方法

<script language="javascript">
<!--
        
//初始化节点
        initchecknode(document.all("tvItemClientID").value,document.all("checked").value)
        
            
//初始化选中节点
            function initchecknode(tree,tvvalue)
            
{
                
//获得需要初始化选择状态的节点的字符串.
                var selectedNodes = tvvalue;
                
var arrayNodes = new Array();
                arrayNodes 
= selectedNodes.split(",");
                
var AllRootNode=new Array();
                AllRootNode
=document.getElementById(tree).getChildren();
                
//初始化选择的节点
                findAndCheckedNodes(AllRootNode,arrayNodes);
            }


            
//根据已选择的节点的字符串初始化选择的节点
            function findAndCheckedNodes(NodeArray,nodeDatas)
            
{
                
//alert(NodeArray.length);
                 if(parseInt(NodeArray.length)==0)
                 
{
                    
return;
                }

                
else
                
{
                    
for(var i=0;i<parseInt(NodeArray.length);i++)
                    
{
                        
var cNode,nodeData;
                        cNode
=NodeArray[i];
                        
////如果该节点在nodeDatas里则初始化checked = true;
                        nodeData = cNode.getAttribute("NodeData");
                        
for(var j=0;j<nodeDatas.length;j++)
                        
{
                            
if(nodeDatas[j] == nodeData)
                            
{
                                cNode.setAttribute(
"checked","true");
                                
break;
                            }

                        }

                        
//如果有子节点,则继续递归
                        if(parseInt(cNode.getChildren().length)!=0)
                        findAndCheckedNodes(cNode.getChildren(),nodeDatas);    
                    }

                }

            }

//-->
//
oncheck事件
function tree_oncheck(tree)
{
 
var i;
 
var node=tree.getTreeNode(tree.clickedNodeIndex);
 
var Pchecked=tree.getTreeNode(tree.clickedNodeIndex).getAttribute("checked"); 
 setcheck(node,Pchecked);
 setParent(node,Pchecked);
//window.alert(Pchecked);
 document.all.checked.value = "";
 
if (tree.getChildren().length > 0)
 
{
    
for (i=0;i<=tree.getChildren().length-1;i++)
    
{
        
if (tree.getChildren()[i].getAttribute("Checked"))
        
{
             AddChecked(tree.getChildren()[i]);
        }
    
        FindCheckedFromNode(tree.getChildren()[i]);
    }

 }

}

//设置子节点选中

function setcheck(node,Pchecked)
{
 
var i;
 
var ChildNode=new Array();
 ChildNode
=node.getChildren();
 
 
if(parseInt(ChildNode.length)==0)
 
{
  
return;
 }

 
else
 
{
  
for(i=0;i<ChildNode.length;i++)
  
{
   
var cNode;
   cNode
=ChildNode[i];
   cNode.setAttribute(
"Checked",Pchecked);
   
//cNode.Checked = Pchecked;
   if(parseInt(cNode.getChildren().length)!=0)
   
{
    setcheck(cNode,Pchecked);
   }

  }

 }

}


//设置子节点选中/取消;
//
同时需要设置父节点的状态(如果是取消选中的话,仅仅设置本节点及其所有字接点,不涉及父接点)
function setParent(node,Pc)
{
    
var parentNode = node.getParent();
 
    
if(parentNode)
    
{    
    
        
var parentNodeFather = parentNode.getParent();
        
        
if(parentNodeFather)
        
{
            setParent(parentNode,Pc);
        }

        
if(Pc)
            
{parentNode.setAttribute("checked",Pc);}
        
else
        
{
            checkBrother(parentNode,Pc,node.getAttribute(
"NodeData"))
        }

    }

}


//检查子接点是否有选择的,如果有一个选择了,那返回true
//
只查第一级节点.
function checkBrother(parentNode,Pc,NodeData)
{
    
var childNodes = new Array();
    childNodes 
= parentNode.getChildren();
    
if(childNodes.length >0)
    
{
        
var bChecked = true;
        
for(var i=0;i<childNodes.length;i++)
        
{
            
if(childNodes[i].getAttribute("checked"== true &&  childNodes[i].getAttribute("NodeData"!= NodeData)
            
{
                
//alert(i+childNodes[i].getAttribute("Text"));
                bChecked = false;
                
break;
            }

        }

        
if(bChecked)
        
{
            parentNode.setAttribute(
"checked",Pc);
        }

        
else
        
{
            
//所有父结点选择
            setParent(parentNode,!Pc)
        }

    }

    
else
    
{
        parentNode.setAttribute(
"checked",Pc);
    }

}


//获取所有节点状态
function FindCheckedFromNode(node)
{
 
var i = 0;
 
var nodes = new Array();
 nodes 
= node.getChildren();
 
 
for (i = 0; i <= nodes.length - 1; i++
 
{
     
if (nodes[i].getAttribute("Checked"))
     
{
         AddChecked(nodes[i]);
     }

     
if (parseInt(nodes[i].getChildren().length) != 0 )
     
{
         FindCheckedFromNode(nodes[i]);
     }

 }

}

//添加选中节点
function AddChecked(node)
{
    document.all.checked.value 
+= node.getAttribute("NodeData"+ ",";
}


//-->
        </script>

这种方法有个很大的问题,就是他客户端设置的CheckBox在服务器端是不能获取的,现在只能在Check的时候遍历树,并把Checked的值放在一个文本里,然后提交到服务器,然后服务器来解析1@2@这种字符
            现在我使用的是asp.net2.0,使用的是以下的方法

function public_GetParentByTagName(element, tagName) 
{
    
var parent = element.parentNode;
    
var upperTagName = tagName.toUpperCase();
    
//如果这个元素还不是想要的tag就继续上溯
    while (parent && (parent.tagName.toUpperCase() != upperTagName)) 
    
{
        parent 
= parent.parentNode ? parent.parentNode : parent.parentElement;
    }

    
return parent;
}


//设置节点的父节点Cheched——该节点可访问,则他的父节点也必能访问
function setParentChecked(objNode)

    
var objParentDiv = public_GetParentByTagName(objNode,"div");
    
if(objParentDiv==null || objParentDiv == "undefined")
    
{
        
return;
    }

    
var objID = objParentDiv.getAttribute("ID");
    objID 
= objID.substring(0,objID.indexOf("Nodes"));
    objID 
= objID+"CheckBox";
    
var objParentCheckBox = document.getElementById(objID);
    
if(objParentCheckBox==null || objParentCheckBox == "undefined")
    
{
        
return;
    }
 
    
if(objParentCheckBox.tagName!="INPUT" && objParentCheckBox.type == "checkbox")
    
return
    objParentCheckBox.checked 
= true;
    setParentChecked(objParentCheckBox);
}


//设置节点的子节点uncheched——该节点不可访问,则他的子节点也不能访问
function setChildUnChecked(divID)

    
var objchild = divID.children;
    
var count = objchild.length; 
    
for(var i=0;i<objchild.length;i++)
    
{
        
var tempObj = objchild[i];
        
if(tempObj.tagName=="INPUT" && tempObj.type == "checkbox")
        
{
            tempObj.checked 
= false;
        }

        setChildUnChecked(tempObj); 
    }

}


//设置节点的子节点cheched——该节点可以访问,则他的子节点也都能访问
function setChildChecked(divID)

    
var objchild = divID.children;
    
var count = objchild.length; 
    
for(var i=0;i<objchild.length;i++)
    
{
        
var tempObj = objchild[i];
        
if(tempObj.tagName=="INPUT" && tempObj.type == "checkbox")
        
{
            tempObj.checked 
= true;
        }

        setChildChecked(tempObj); 
    }

}


//触发事件
function CheckEvent()
{

    
var objNode = event.srcElement; 

    
if(objNode.tagName!="INPUT" || objNode.type!="checkbox")
    
return;

    
if(objNode.checked==true)
    
{
        setParentChecked(objNode);
        
var objID = objNode.getAttribute("ID");
        
var objID = objID.substring(0,objID.indexOf("CheckBox")); 
        
var objParentDiv = document.getElementById(objID+"Nodes");
        
if(objParentDiv==null || objParentDiv == "undefined")
        
{
            
return;
        }
 
        setChildChecked(objParentDiv);
    }

    
else
    
{
        
var objID = objNode.getAttribute("ID");
        
var objID = objID.substring(0,objID.indexOf("CheckBox")); 
        
var objParentDiv = document.getElementById(objID+"Nodes");
        
if(objParentDiv==null || objParentDiv == "undefined")
        
{
            
return;
        }
 
        setChildUnChecked(objParentDiv);
    }

}

这种方法最大的好处就是服务端能得javascript设置的Checked的值,不用没点下就全部把树遍利下,直接在服务端遍利一次就行了

    //遍历子节点
    public void GetChildNode(TreeNode Node)
    
{
        
foreach (TreeNode node in Node.ChildNodes)
        
{
            
if (node.Checked)
            
{
                StrChecked 
+= node.Value+"@";
            }

            GetChildNode(node);
        }

    }

}

我照样能得到它的Check的值