今天爲大家介紹下angular-ui-tree的使用方法,它是一個不依賴於jquery 的angualrJS UI,友好的外觀,方便的操作,是它最大的優勢。
angular-ui-tree有如下特點:
1.使用本地AngularJS範圍數據綁定
2.整個樹都可以進行排序和移動項目
3.防止上級節點創建子節點
廢話不多說,下面上效果圖
拖拽效果:
節點的添加
官方DEMO:http://angular-ui-tree.github.io/angular-ui-tree/
angular-ui-tree 下載地址: https://github.com/angular-ui-tree/angular-ui-tree
前端使用代碼如下:
index.js
1、 載入angular-ui-tree.css 和 angular-ui-tree.js
2、module中加入依賴
使用頁面中的代碼
html
<script type="text/ng-template" id="angularTreeTemplate">
<div ui-tree-handle class="tree-node tree-node-content angular-ui-tree-handle">
<a class="btn btn-success btn-xs" ng-if="item.children && item.children.length > 0" data-nodrag ng-click="toggle(this)">
<span class="glyphicon" ng-class="{'glyphicon-chevron-right': collapsed, 'glyphicon-chevron-down': !collapsed }"></span>
</a>
<span ng-show="item.isEdit">
<input style="width:40%" type="text" data-nodrag ng-model="item.name" />
</span>
<span ng-show="!item.isEdit">
{{ item.name | limitTo: 5 }}{{item.name.length > 5 ? '...' : ''}}
</span>
<a ng-hide="item.children.length>0||item.level==0" class="pull-right btn btn-danger btn-xs" data-nodrag ng-click="removeItem(item)||remove(this)">
<span class="glyphicon glyphicon-remove"></span>
</a>
<a ng-show="item.level<dept" class="pull-right btn btn-primary btn-xs" data-nodrag ng-click="newSubItem(item)">
<span class="glyphicon glyphicon-plus"></span>
</a>
<a ng-show="item.level>0" class="pull-right btn btn-warning btn-xs" data-nodrag ng-click="editItem(item)">
<span class="glyphicon glyphicon-edit"></span>
</a>
<a ng-show="dept==1||item.level>1" class="pull-right btn btn-info btn-xs" data-nodrag ng-click="selectTreeItem(item)">
<span class="glyphicon glyphicon-search"></span>
</a>
</div>
<ol ui-tree-nodes="" style="padding-left:10px;" ng-model="item.children" ng-class="{hidden: collapsed}">
<li ng-repeat="item in item.children" ui-tree-node ng-include="'angularTreeTemplate'">
</li>
</ol>
</script>
<div ui-tree="treeOptions" id="tree-root">
<ol ui-tree-nodes ng-model="angularTreeList">
<li ng-repeat="item in angularTreeList" ui-tree-node ng-include="readonly?'angularTreeReadOnlyTemplate':'angularTreeTemplate'">
</li>
</ol>
</div>
上段代碼中 dept 參數決定了樹的深度,決定了樹到第幾級不在繼續創建子節點,我們可以自行配 。
在標籤上加入data-nodrag表示此功能不受拖動的影響 ,保證了次功能能夠正確使用,不被拖動效果所覆蓋,如input的聚焦效果 。
ui-tree-handle爲節點拖動的指令,自由的使用或刪除它我們可以限制某些特定節點禁止拖動
前端用ng-include 這種形式 模擬後端生成樹
js
$scope.init=function(){
$scope.getTreeList();
}
$scope.getTreeList=function(){
OrganizationService.getOrgTreeList().then(function(result) {
$scope.angularTreeList=[];
//查詢樹
$scope.orgTypeList=result;
//創建根節點
var root={};
root.name="法制機構";
root.level=0;
root.sequence=1;
root.orgTypeId=-1;
root.children=$scope.orgTypeList;
$scope.angularTreeList.push(root);
$scope.treeOptions.data=$scope.angularTreeList;
});
}
//新建節點
$scope.newSubItem = function (item) {
var name=window.prompt("請輸入節點的名稱");
if(name==""||name==undefined){
return;
}
if(item.orgTypeId==undefined){
item.orgTypeId=-1;
}
var json={"level":parseInt(item.level)+1,"name":name,"parentTypeId":item.orgTypeId,"children":[]};
if(item.children==null||item.children.length==0){
item.children=[];
json.sequence=1;
}else{
var maxSequence=parseInt(item.children[item.children.length-1].sequence);
json.sequence=maxSequence+1;
}
OrganizationService.saveOrgType(json).then(function(result) {
// item.children.push(json);
$scope.init();
});
};
//編輯節點
$scope.editItem=function(item){
// var target=$("#div_"+item.orgTypeId);
if(item.isEdit==undefined||item.isEdit==false){
item.isEdit=true;
// $(target).removeAttr("ui-tree-handle");
}else if(item.isEdit==true){
item.isEdit=false;
// $(target).attr("ui-tree-handle",'');
var json={"orgTypeId":item.orgTypeId,"name":item.name}
OrganizationService.updateOrgType(json).then(function(result) {
// $scope.init();
});
}
}
//刪除節點
$scope.removeItem=function(item){
var json={};
json.orgTypeId=item.orgTypeId;
json.status=0;
OrganizationService.updateOrgType(json).then(function(result) {
// $scope.init();
});
}
$scope.treeOptions = {
//拖拽操作 拖拽後會返回callback beforeDrop函數,我們可以重寫這個函數,拖拽本質上是順序的改變和層級的改變,所以是一個update操作
beforeDrop : function (e) {
var source = e.source.nodeScope.item;
var destRoot = e.dest.nodesScope.item ;
if(destRoot==undefined){
return $q.reject();
}
var destIndex=e.dest.index;
var dest=e.dest.nodesScope.item.children[destIndex];
if(dest==undefined){
return $q.reject();
}
if (source.parentTypeId!=dest.parentTypeId) {
return $q.reject();
}
var sourceSeq=source.sequence;
var destSeq=dest.sequence;
source.sequence=destSeq;
dest.sequence=sourceSeq;
OrganizationService.updateOrgType(source).then(function(result) {
});
OrganizationService.updateOrgType(dest).then(function(result) {
});
return;
}
};
注:treeOptions中還有removed,dropped等回調方法,這裏沒有講述,具體請看angular-ui-tree.js 源碼
本例中的拖拽操作默認爲只能同級節點之間拖拽才能生效,不是同級自動取消,當然,不是同級完全自由的也可以實現,在使用的過程中,請根據自身業務需求及數據結構自行規定拖動的規則,angular-ui-tree默認的規則是全部可以自由拖動的
最後是後端實體的結構
public class OrganizationType extends BaseEntity {
//組織類型id
private String orgTypeId;
//code
private String code;
//排序
private String sequence;
//層級
private String level;
//類型名稱
private String name;
//父類型id
private String parentTypeId;
private List<OrganizationType> children;
public List<OrganizationType> getChildren() {
return children;
}
public void setChildren(List<OrganizationType> children) {
this.children = children;
}
public String getOrgTypeId() {
return orgTypeId;
}
public void setOrgTypeId(String orgTypeId) {
this.orgTypeId = orgTypeId;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getParentTypeId() {
return parentTypeId;
}
public void setParentTypeId(String parentTypeId) {
this.parentTypeId = parentTypeId;
}
public String getSequence() {
return sequence;
}
public void setSequence(String sequence) {
this.sequence = sequence;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public String toString() {
return "OrganizationType [orgTypeId=" + orgTypeId + ", code=" + code + ", sequence=" + sequence + ", level="
+ level + ", name=" + name + ", parentTypeId=" + parentTypeId + ", children=" + children + "]";
}
}
查詢樹
@RequestMapping("/getOrgTreeList.do")
@ResponseBody
public List<OrganizationType> getOrgTreeList(){
List<OrganizationType> orgTypeList= new ArrayList<OrganizationType>();
OrganizationType orgType=new OrganizationType();
orgType.setParentTypeId("-1");
orgTypeList=orgTypeService.findOrgTypeList(orgType); //把根查出來
fillTree(orgTypeList);
return orgTypeList;
}
public void fillTree(List<OrganizationType> orgTypeList){
if(orgTypeList!=null){
for(OrganizationType orgType : orgTypeList){
OrganizationType type=new OrganizationType();
type.setParentTypeId(orgType.getOrgTypeId());
List<OrganizationType> orgChildList=orgTypeService.findOrgTypeList(type);
orgType.setChildren(orgChildList);
fillTree(orgChildList);
}
}
}