You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Telerik UI Grid配置:新增行全可编辑,更新时仅部分列可编辑

搞定Telerik Grid单元格编辑:新增行全可编辑,现有行仅部分列可编辑

嘿,我明白你遇到的问题了——你想让新增的行所有单元格都能编辑,但现有行只有部分列(比如Description和Count)可编辑,结果用Edit事件修改字段可编辑性后,把现有行的Title也搞成可编辑了。这其实是因为你修改的是全局的字段配置,不是单独行的设置,所有行共享同一个字段模板,所以改了之后全变了。

下面给你两种适配Telerik UI v2020.2.617版本的解决方案,选哪个都行:

方案一:列定义直接加判断(最简洁)

这种方式不用写额外的JS事件,直接在列绑定的时候指定可编辑逻辑,非常直观:

@(Html.Kendo().Grid<DataViewModel>()
    .Name("DataGrid")
    .Columns(columns => {
        columns.Bound(model => model.Title)
            .Editable(dataItem => dataItem.IsNew()); // 只有新行的Title能编辑
        columns.Bound(model => model.Description); // 默认所有行都能编辑
        columns.Bound(model => model.Count); // 默认所有行都能编辑
    })
    .Editable(edit => edit.Mode(GridEditMode.InCell))
    .ToolBar(toolbar => {
        toolbar.Create();
        toolbar.Save();
    })
    .DataSource(dataSource => dataSource
        .Ajax()
        .Batch(true)
        .ServerOperation(false)
        .Read("DataRead", "Data")
        .Create("DataCreate", "Data")
        .Update("DataUpdate", "Data")
        .Model(model => {
            model.Id(x => x.Id);
            // 这里不用再设置Title.Editable(false),交给上面的列回调处理就行
        })
    )
)

核心就是列的Editable方法接受一个回调函数,参数是当前行的数据项,用IsNew()判断是不是新行,直接决定该列能不能编辑,完全不会影响其他行的配置。

方案二:Edit事件里控制当前单元格(适合复杂场景)

如果你需要在编辑时做更多自定义逻辑,比如根据其他字段值判断权限,可以用这个方法——直接操作当前编辑的单元格,不碰全局字段配置:

<script>
'use strict';
function onEdit(event) {
    // 不是新行的话,检查当前编辑的是不是Title列
    if (!event.model.isNew()) {
        const field = event.container.parent().data('field');
        if (field === "Title") {
            // 禁用输入控件,或者直接取消编辑
            event.container.find('input').prop('disabled', true);
            // 或者用event.preventDefault()直接阻止编辑动作
        }
    }
}
</script>

@(Html.Kendo().Grid<DataViewModel>()
    .Name("DataGrid")
    .Columns(columns => {
        columns.Bound(model => model.Title);
        columns.Bound(model => model.Description);
        columns.Bound(model => model.Count);
    })
    .Editable(edit => edit.Mode(GridEditMode.InCell))
    .ToolBar(toolbar => {
        toolbar.Create();
        toolbar.Save();
    })
    .Events(events => events.Edit("onEdit"))
    .DataSource(dataSource => dataSource
        .Ajax()
        .Batch(true)
        .ServerOperation(false)
        .Read("DataRead", "Data")
        .Create("DataCreate", "Data")
        .Update("DataUpdate", "Data")
        .Model(model => {
            model.Id(x => x.Id);
            // 这里也不用设置Title.Editable(false)
        })
    )
)

这个思路很简单:当编辑现有行的Title单元格时,直接把输入框禁用,或者干脆阻止编辑事件,这样既不会影响全局字段配置,也能达到现有行Title不可编辑的效果。

为啥原来的方法不行?

再给你解释下根源:Telerik Grid的数据源字段定义是全局共享的,所有数据项用的是同一个fields模板。你在Edit事件里改event.model.fields.Title.editable = true,其实是修改了整个数据源的字段设置,所以后续所有行的Title都变成可编辑了,这就是问题所在。

内容的提问来源于stack exchange,提问作者user10975585

火山引擎 最新活动