AngularJs中动态html包含指令问题

AngularJs中动态html包含指令问题

在使用ui-grid来渲染数据列表的时候,遇到一个问题就是当数据量太大的时候,对于渲染好了的列表,如果再次修改这个列表,重新绑定数据集,ui-grid处理非常慢(大致看了一下源码,里面对于重新绑定的数据集,不会去创建表格,只会从当前的表格中克隆节点,然后再处理,并且其中需要销毁很多的监听器)。一直解决不了,换了一种方式,当数据变化的时候,我就销毁当前表格(其实就是移除了dom节点),然后重新创建一个动态的html片段代码,里面绑定有ui-grid的指令。当我将动态的html插入到文档中之后,然后再设置表格数据,发现表格并没有渲染。

    //创建新表格
    $scope.createNewGrid = function(elementId,headers,datas){
        //获取旧容器
        var container = document.getElementById(elementId);
        var childList = container.childNodes;
        var oldGridContainer = null;
        //找到Grid容器
        for(var i = 0; i < childList.length; i ++){
            if(/DIV/i.test(childList[i].nodeName)){
                oldGridContainer = childList[i];
                break;
            }
        }
        //新表格容器
        var newGridContainer = oldGridContainer.cloneNode(false);
        //销毁就容器
        container.innerHTML = "";
        $scope.newGridOptions = createGridOptions();
        newGridContainer.setAttribute("ui-grid","newGridOptions");
        container.appendChild(newGridContainer);
        //设置数据集
        $scope.newGridOptions.data = datas;
        console.log(newGridContainer);
        /*console.log(uiGrid);*/
    }

上面代码的问题就是,我获取的以前的节点并克隆了一份,当我插入文档之后,该节点包含指令没有被编译,指令没有和作用域连接起来,因此导致了问题。

解决方案:使用angular的$compile来编译指令,compile可以将一个HTML字符串或者DOM编译成模板,该模板能够与scope链接起来,也就是说直接插入一段html片段到页面中,虽然能插入进去,但是angular并没有编译,所以任何ng事件指令绑定都是无效的,通过compile能够将html片段先编译后再插入 。

html代码片段:后面构造表格函数传入的elementId就是这个Id,ui-grid内容就渲染在这个dom之中

    <div class="row">
        <div class="col-md-12" style="padding: 0px;" id="rightGrid">
        </div>
    </div>

关键代码

        //编译指令,并挂载作用域
container.html($compile("<div ui-grid='" + gridOptionsIdentifier +"' ui-grid-selection ui-grid-exporter ui-grid-resize-columns ui-grid-auto-resize></div>")($scope));

改进后的表格创建函数

    //创建新表格API
    $scope.createNewGrid = function(elementId,headers,datas){
        //获取旧容器
        var container = $("#"+elementId);
        //销毁以前的Grid容器
        container.html("");
        //生成Grid唯一标识
        var gridOptionsIdentifier = "gridOptions_"+(new Date()).getTime();
        //生成配置项
        $scope[gridOptionsIdentifier] = createGridOptions(); 
        //编译指令,并挂载作用域
        container.html($compile("<div ui-grid='" + gridOptionsIdentifier +"' ui-grid-selection ui-grid-exporter ui-grid-resize-columns ui-grid-auto-resize></div>")($scope));
        //挂载数据
        $scope[gridOptionsIdentifier].columnDefs = headers;
        $scope[gridOptionsIdentifier].data = datas;
        //将表格绑定到全局变量,以便于后面获取表格API
        if(elementId == "leftGrid"){
            $scope.leftGridOptions = $scope[gridOptionsIdentifier];
        }
        else if(elementId == "rightGrid"){
            $scope.rightGridOptions = $scope[gridOptionsIdentifier];
        }
        else {
            $scope.resultGridOptions = $scope[gridOptionsIdentifier];
        }
        console.clear();
    }

创建表格配置代码

    //创建表格配置
    function createGridOptions(){
        var gridOptions = {};
        (function(arg){
            arg = gridOptions || {};
            arg.enableSorting = true;
            arg.useExternalSorting= false;//是否使用自定义排序规则  
            arg.enableGridMenu= true; //是否显示grid菜单  
            arg.enableHorizontalScrollbar= 1; //grid水平滚动条是否显示, 0-不显示  1-显示  
            arg.enableVerticalScrollbar= 1; //grid垂直滚动条是否显示, 0-不显示  1-显示  
            //----------- 选中 ----------------------  
            arg.showGridFooter= true, //是否显示grid footer
            arg.enableFooterTotalSelected= true; // 是否显示选中的总数,默认为true, 如果显示,showGridFooter 必须为true  
            arg.enableFullRowSelection= false; //是否点击行任意位置后选中,默认为false,当为true时,checkbox可以显示但是不可选中  
            arg.enableRowHeaderSelection= true; //是否显示选中checkbox框 ,默认为true  
            arg.enableRowSelection= true; // 行选择是否可用,默认为true;  
            arg.enableSelectAll= true; // 选择所有checkbox是否可用,默认为true;  
            arg.enableSelectionBatchEvent= true; //默认true  

            arg.isRowSelectable= function (row) { //GridRow  
                $scope.index += 1;       
                if ($scope.index == 1) {  
                    row.grid.api.selection.selectRow(row.entity); // 选中行  
                }  
            },  
            arg.modifierKeysToMultiSelect= false;//默认false,为true时只能 按ctrl或shift键进行多选, multiSelect 必须为true;  
            arg.multiSelect= true;// 是否可以选择多个,默认为true;  
            arg.noUnselect= false;//默认false,选中后是否可以取消选中  
            arg.selectionRowHeaderWidth= 30;//默认30 ,设置选择列的宽度;  
            //---------------api---------------------  
            arg.onRegisterApi=function (gridApi) {  
                arg.gridApi = gridApi;  
                //行选中事件  
                arg.gridApi.selection.on.rowSelectionChanged(arg, function (row, event) {  
                    if (row) {  
                        arg.testRow = row.entity;  
                        arg.isSelected = row.isSelected;  
                        //console.log($scope.gridApi.selection.getSelectedRows());
                    }  
                });
            };
            //获取表格所有数据
            arg.getAllRows = function(){
                return arg.data;
            }
            //----------------导出--------------------
            arg.exporterCsvColumnSeparator = ','; 
            arg.exporterOlderExcelCompatibility = true;//是否兼容低版本excel  
            arg.exporterHeaderFilterUseName = true; 
            arg.exporterMenuCsv = true; 
            arg.exporterMenuLabel = "导出";
            arg.exporterMenuPdf = false;
            return arg;
        })(gridOptions);
        return gridOptions;
    }

猜你喜欢

转载自blog.csdn.net/lq15310444798/article/details/81105464