剑道UI隐藏栏/显示栏性能与许多栏



我正试图使用Kendo UI的hidecolumn和showcolumn方法隐藏和显示网格中的列,它可以工作,但当网格中有很多列时,网格在显示和隐藏列方面似乎滞后。我的网格中大约有50列。同样,在隐藏列之后,即使使用了网格的刷新方法,列也不会在网格中重新排列。有人知道在不降低网格性能的情况下隐藏/显示列的另一种方法吗?

谢谢。Sanjeev

首先,您只需要知道,网格中的列只不过是普通的数组。因此,您可以单独创建此阵列,并将其分配到网格配置中。

我这样做是为了配置整个网格,但我尝试只显示列的部分,因为这个例子会比较长,因为我会尝试显示所有重要的方法。不管怎样,我希望它能帮助你。

所以过程可以(但不一定)是这样的:

  1. 准备数据库表。如果你只需要保存可见/隐藏的值,你可以满足于这样的基本表:

    CREATE TABLE dbo.TableSettings( 
        Id INT PRIMARY KEY IDENTITY, 
        [Key] VARCHAR(MAX) NOT NULL, 
        Name VARCHAR(MAX) NULL, 
        Value BIT NULL );
    

    在我的例子中,表有更多的列,但对于保存这些信息来说,这已经足够了。在我的例子中,[Key]是表名(例如dbo.[User]),name是列名(例如FirstName),Value是Visible/hid(1/0)。

  2. 现在,您需要从数据库中加载列设置,并将其保存到数组中。该数组将被分配到网格配置中。

    RunSynchronousAjax(address, null, function (e) {
        var options = JSON.parse(e.Config);
        var columns = options.Columns;
        //This part is needed only if you have some special cases which are prepared on server. It is because on server you cannot assign function like in javascript but you have to assign only name of function which need to be eval in javascript.
        for (var i = 0; i < options.columns.length; i++) {
            options.columns[i].filterable.ui = eval(options.columns[i].filterable.ui);
            if (options.columns[i].filterable.itemTemplate != undefined) {
                options.columns[i].filterable.itemTemplate = eval(options.columns[i].filterable.itemTemplate);
            }
        }
    }, defaultErrorCallBack);
    

    注意:RunSynchronousAjax是我处理ajax请求的辅助方法,因为我不想在每次需要的时候都写它

    function RunSynchronousAjax(url, data, successCallback, errorCallback) {
        jQuery.ajax({
            contentType: 'application/json; charset=utf-8',
            url: url,
            data: data,
            type: "POST",
            cache: false,
            success: function (json) {
                successCallback(json);
            },
            error: function (data) {
                errorCallback(data);
            },
            async: false
        });
    }
    function defaultErrorCallback(data) {
        alert("Unexpected error. Please, try press CTRL+F5.");
    }
    
  3. 这个函数就是我为表加载配置的方式,现在让我们看看控制器中的方法。

    public JsonResult GetSetting()
    {
        KendoGrid grid = new KendoGrid();
        grid.PrepareColumns();
        string json = JsonConvert.SerializeObject(grid);
        return Json(new
        {
            Config = json
        });
    }
    
  4. 对象看起来像这个

    public class KendoGrid
    {
        ...
        private List<Column> _Columns = new List<Column>();
        [JsonProperty("columns")]
        public List<Column> Columns
        {
            get { return this._Columns; }
            set { this._Columns = value; }
        }
        ...
    }
    public class Column
    {
    
        [JsonProperty("field")]
        public string Field { get; set; }
        [JsonProperty("title")]
        public string Title { get; set; }
        [JsonProperty("type")]
        public string Type { get; set; }
        [JsonProperty("width")]
        public string Width { get; set; }
        [JsonProperty("filterable")]
        public object Filterable { get; set; }
        [JsonProperty("template")]
        public string Template { get; set; }
        [JsonProperty("order")]
        public int Order { get; set; }
        [JsonProperty("format")]
        public string Format { get; set; }
       .... and more ... just what you need
        public Column(
            string field,
            string title = null,
            string type = "string",
            string width = null,
            string template = null,
            object filterable = null,
            string format = null,
            ...)
        {
            this.Field = field;
            this.Title = title ?? field;
            this.Type = type;
            this.Width = width;
            this.Template = template;
            this.Order = order;
            this.Format = format;
            ....
        }
    
  5. 在第3点中有一个方法PrepareColumns,它看起来像这个

    public void PrepareColumns()
        {
            var listOfColumns = TableSettings.GetColumns("dbo.TableName");
            this.Columns.AddNotNull(Column.GetColumn<ObjectWhichIsDisplayedInGrid>(x => x.Id, listOfColumns,
            type: "number",
            width: "140px", 
            ...));
            this.Columns.AddNotNull(Column.GetColumn<ObjectWhichIsDisplayedInGrid>(x => x.Name, listOfColumns,
                width: "250px",
                ...));
    .....
    }
    //This method is based on you, It just load records from db...
    
    public static List<TableSettings> GetColumns(string key)
        {
    
            List<TableSettings> result = new List<TableSettings>();
            var query = Sql.Builder
                .Select("*")
                .From("dbo.TableSettings")
                .Where("[Key] = @0", key)
                .OrderBy("OrderInTable");
            using (IDatabase db = DbConnection.Connect())
            {
                result = db.Fetch<TableSettings>(query);
            }
            return result;
        }
    
    public static Column GetColumn<T>(
        Expression<Func<T, object>> expression,
        List<TableSettings> settings,
        string type = "string",
        string width = null,
        string template = null,
        ...)
        {
    
            var fieldName = PropertyNameHelper.PropertyName<T>(expression);
            var fieldDescription = PropertyNameHelper.PropertyDescription<T>(expression);
            var column = settings.Where(c => c.Name.Replace(" ", string.Empty).ToLower() == fieldName.Replace(" ", string.Empty).ToLower()).FirstOrDefault();
            Column col = new Column(
            field: fieldName,
            title: fieldDescription,
            type: type,
            ....);
            return col;
        }
    public static string PropertyName<T>(Expression<Func<T, object>> expression)
        {
            return GetPropertyName(expression);
        }
    public static string PropertyDescription<T>(Expression<Func<T, object>> expression)
        {
    
            var propertyName = GetPropertyName(expression);
            PropertyInfo prop = typeof(T).GetProperty(propertyName);
            if (prop.IsDefined(typeof(DisplayAttribute), false))
            {
                return (prop.GetCustomAttribute(typeof(DisplayAttribute), false) as DisplayAttribute).Name;
            }
            return propertyName;
        }
    
  6. 就是这样。前5点是关于从数据库加载列的配置。保存为不可见的内容将不会加载,因此剑道网格将只知道可见的列。

现在,我已经谈到了我自己的专栏菜单。这是唯一常见的带有选项的弹出窗口。重要的是,网格已经将columnMenu设置为false,所以默认功能是关闭的。我在工具栏中添加了按钮,点击事件打开了kendoWindow,在那里我有带列名的复选框。我可以检查我想要显示的内容,在弹出窗口关闭/确认后,会调用一些ajax请求——它被保存到数据库中,并刷新网格。

不管怎样,它主要可以给你一些想法,我相信还有更多的解决方案。若你们找到了如何动态创建列数组的方法,你们将获胜。

最新更新