自己动手,通过源码找回 Ant-Design-Blaozr 中 Tree 组件的搜索筛选效果
最近更新一个Blazor server的项目,顺带把用到的 Ant-Design-Blazor 升级到了最新的 0.14.4,结果发现之前在 0.8.4 版本中 Tree 组件的搜索显示效果变了,从仅显示找到的节点变成了在全部节点中高亮显示匹配的结果,为了节省用户沟通成本(就是懒得跟最终用户费口舌解释),于是自己动手把这个筛选效果找回来。
从 github 上拉取最新的 ant 代码回来,找到 Tree.Razor.cs 中的 SearchValue 属性,顺藤摸瓜找到 TreeNode.razor.cs 中的 RealDisplay 属性,参考 0.8.4 的实现把它改回去
internal bool RealDisplay { get { if (string.IsNullOrEmpty(TreeComponent.SearchValue)) { //普通模式下节点显示规则 if (ParentNode == null) return true; //第一级节点默认显示 if (ParentNode.Expanded == false) return false; //上级节点如果是折叠的,必定折叠 return ParentNode.RealDisplay; //否则查找路径三的级节点显示情况 } else { //筛选模式下不考虑节点是否展开,只要节点符合条件,或者存在符合条件的子节点是就展开显示 return Matched || HasChildMatched; } } }
信心满满地运行,搜索结果的筛选效果确实是实现了,但是——所有匹配节点的上级节点全丢了——什么情况?原路找回 SearchNodes() 方法,应该是调用 node.OpenPropagation 方法时没有设置父节点的 HasChildMatched 属性,补上
internal void OpenPropagation() { this.Expand(true); if (this.ParentNode != null) { this.ParentNode.HasChildMatched = true; this.ParentNode.OpenPropagation(); } }
这下才算是彻底恢复了之前的搜索结果的显示效果。个人感觉原来的筛选效果挺好的,即使新版本增加了 MatchedStyle 和 MatchedClass 突出显示结果,也可以保留筛选啊,想不通为啥要去掉。
因为是自己用,所以把生成的 AntDesign.dll 文件直接替换掉 C:\Users\用户名\.nuget\packages\antdesign\0.14.4\lib\net6.0 下的同名文件后 再重新生成引用它的项目就可以了。由于没有改动 AntDesign 的接口,其实直接替换发布目录下的同名文件应该也是可以的。
PS:借着这个机会,走马观花地学习了一下 AntDesign 的源代码,意外的发现一个动态生成 RenderFragment 的小技巧
var value = $"{start}<span class=\"{TreeComponent.MatchedClass}\" style=\"{TreeComponent.MatchedStyle}\">{match}</span>{end}"; <span> @((MarkupString)value) </span>
这显然比单独写函数返回 RenderFragment 直观省事得多。不过当 RenderFragment 作为模板时不能用函数传参了,需要通过 Inline 方式通过委托动态传参。例如要给 Table 组件的 FooterTemplate 传参
<Table FooterTemplate="@footer(sumValue)" ...省略了... > ...也省略了... </Table>
需要用以下方式
RenderFragment<float> footer = (v) => (RenderTreeBuilder __builder) => { <span style="font-weight:bold"> 预估金额总计: @v.ToString("¥0.00") </span> };
最后,感谢 Ant-Design-Blazor 的作者James Yeung和其他贡献者,感谢开源。