【问题标题】:Kendo UI hidecolumn/showcolumn performance with many columnsKendo UI hidecolumn/showcolumn 性能与许多列
【发布时间】:2015-12-18 17:21:23
【问题描述】:

我正在尝试使用 Kendo UI hidecolumn 和 showcolumn 方法隐藏和显示我的网格中的列,它可以工作,但是当网格中有很多列时,它看起来网格在显示和隐藏列时滞后。我的网格中有大约 50 列。同样在隐藏列之后,即使使用网格的刷新方法,列也不会在网格中重新对齐。 有谁知道在不损失网格性能的情况下隐藏/显示列的另一种方法是什么?

谢谢。 桑吉夫

【问题讨论】:

  • 我已经在服务器端完成了这个功能。并且每个更改(隐藏/显示)都保存到数据库中。因此,当用户访问页面时,只显示“活动”列,我对性能没有任何问题。我唯一需要更改的是“列菜单”,我没有显示默认菜单,而是创建了按钮(在工具栏中),它打开带有列选项的对话框窗口......也许这种方法对你也有帮助。如果您有兴趣,我可以发布一些简短的示例,但请注意,我不是 kendo grid mvc 的所有者,所以我只能显示 kendo grid javascript 语法..
  • @Ademar,您可以为此发布您的简短示例吗?

标签: javascript asp.net-mvc kendo-ui kendo-grid


【解决方案1】:

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

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

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

  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。它只是通常的带有选项的弹出窗口。重要的是网格已将 columnMenu 设置为 false,因此默认功能已关闭。我已将按钮添加到工具栏中,并且单击事件已打开 kendoWindow,其中我有带有列名称的复选框。我可以检查我想要显示的内容,在弹出窗口关闭/确认后,会调用一些 ajax 请求 - 它被保存到数据库中并刷新网格。

无论如何,它主要可以给你一些想法,我相信还有更多的解决方案。如果您找到动态创建列数组的方法,您将获胜。

【讨论】:

    猜你喜欢
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多