TuiEditor 组件中有个参数 TuiEditorOptions ,是要对应 JavaScript 中的 options 参数的,我们需要自己定义一个,这里我们使用两个类来使用,一个是针对 JavaScript 的 JsParams 类似字典的对象,一个是针对使用者的 TuiEditorOptions 。
JsParams 就是一个Dictionary<string,object>,为了方便,我们过滤了空值:
TuiEditorOptions 类除了参数之外,包含一个 ToParams() 的方法把自己转换成 JsParams:
public class TuiEditorOptions { internal string elid { get; set; } /// <summary> /// Editor's height style value. Height is applied as border-box ex) '300px', '100%', 'auto' /// </summary> public string Height { get; set; } /// <summary> /// 是否是查看器 /// </summary> public bool? Viewer { get; set; } //...其他参数 internal JsParams ToParams() { JsParams ps = new JsParams(); var def = BulmaRazorOptions.DefaultOptions.TuiEditorOptions; ps.AddNotNull("elid", elid); ps.AddNotNull("viewer",Viewer); ps.AddNotNull("height", Height ?? def.Height); //...其他参数 return ps; } }有几个原因使用 JsParams :
null值可以不传递,因为js的options一般都用默认值,减少传输;
可以使用默认设置,如上有个BulmaRazorOptions.DefaultOptions.TuiEditorOptions;
可以灵活的手动处理参数,上面例子没有提现出来,不过组件写多了肯定会遇到这种情况;
对象的方法JavaScript 组件一般也会公开许多实例方法,比如获得焦点,设置内容,获取内容等等,在在前面我们一直保存了 JavaScript 组件实例的引用,也就是在 TuiEditor 中的 editor 对象,向公开哪些方法在 TuiEditor.razor 中添加就是了:
public void Focus() { editor?.InvokeVoidAsync("focus"); } public ValueTask<string> GetMarkdown() { return editor?.InvokeAsync<string>("getMarkdown") ?? new ValueTask<string>(""); } public void InsertText(string text) { editor?.InvokeVoidAsync("insertText", text); } public ValueTask<bool> IsViewer() { return editor?.InvokeAsync<bool>("isViewer") ?? new ValueTask<bool>(false); } //...其他需要的方法 对象事件JavaScript 组件对象有自己的事件,在 JavaScript 中直接设置 JavaScript 函数就可以了,但是并不能把 C# 方法或者委托传递给 js,这里就需要用到 JavaScript 调用C#方法了。
Blazor 框架中 JavaScript 只能调用静态方法,而我们实际中是基于对象来写逻辑的,所有我专门写了一个类来处理js的调用,JSCallbackManager:
我们使用一个嵌套的字典来保存了Blazor组件的回调委托,每一个组件对象都有一个唯一的Id,每一个组件类型都可以有不同名称的 JavaScript 事件回调。
比如我们想订阅 JavaScript 组件实例的 load 事件,我们需要改两个地方,第一个是 toastui-editor-export.js 导出文件:
JavaScript 的事件还是需要用 js来做,然后在js方法内部调用 C# 方法。第二个是需要在 TuiEditor 中添加回调委托:
[Parameter] public EventCallback<TuiEditor> OnLoad { get; set; } protected override void OnInitialized() { if (Options == null) Options = new TuiEditorOptions(); Options.elid = Id; //这里添加回调委托,并把js事件公开成了Blazor组件事件 JSCallbackManager.AddEventHandler(Id, "load", new Func<Task>(() => OnLoad.InvokeAsync(this))); base.OnInitialized(); } protected override ValueTask DisposeAsync(bool disposing) { //移除对象的所有回调委托 JSCallbackManager.DisposeObject(Id); return base.DisposeAsync(disposing); }这样我们就把 JavaScript 组件事件移植到了 Blazor 组件。
修整