2

我正在修改文本区域元素上的 CodeMirror。我正在使用 javascript interop 来完成此操作,并且在应用代码镜像时它工作正常。但是,我的意图是返回该 codemirror 元素并将其存储在另一个 elementref 中。

Blazor.registerFunction('BlazorExt.CodeMirrorSetupExt', (element) =>
{
    return CodeMirror.fromTextArea(element,
    {
        mode: 'application/ld+json',
        matchBrackets: true,
        autoCloseBrackets: true,
        indentWithTabs: true,
        lineNumbers: true,
        autofocus: true,
        styleActiveLine: true,
        readOnly: false,
        autoCloseBrackets: true,
        foldGutter: true,
        height: 'auto',
        width: 'auto',
        gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter']
    });
});

        public static ElementRef CodeMirrorSetupExt(this ElementRef elementRef)
    {
        var result = RegisteredFunction.Invoke<ElementRef>("BlazorExt.CodeMirrorSetupExt", elementRef);
        return result;
    }

在我的组件中:

//in my html i have a textarea with ref of TextArea

ElementRef CodeMirror;
ElementRef TextArea;

protected override void OnAfterRender()
{

    CodeMirror = TextArea.CodeMirrorSetupExt();
}

理想情况下,在这一点之后,我应该能够使用它的函数来更新我的 codemirror ref。

    Blazor.registerFunction('BlazorExt.CodeMirrorUpdateExt', (element, Value) =>
{
    element.getDoc().setValue(Value);
});

        public static void CodeMirrorUpdateExt(this ElementRef elementRef, string Value)
    {
        var args = new object[] { elementRef, Value };
        RegisteredFunction.Invoke<object>("BlazorExt.CodeMirrorUpdateExt", args);
    }

再次在组件中,我应该能够像这样更新代码镜像:

CodeMirror.CodeMirrorUpdateExt("somedata");

但是我得到一个例外: Microsoft.AspNetCore.Blazor.Browser.Interop.JavaScriptException: 无法读取 null 的属性“getDoc”

是我试图在可能之外完成的事情,还是不可能将 codemirror javascript 对象传递给 elementref?

4

2 回答 2

1

我扩展了@Flores 的答案。无需创建所有 javascript 对象的全局数组,只需将新值存储在您已经拥有 elementReference 的 javascript DOM 对象中。

window.hintCodeMirrorIntegration = {
    initialize: function(element, markupMode) {
        element.codeMirrorLink = CodeMirror.fromTextArea(element,
           {
            ...
            });
        return 0;
    },

    getCode: function(element) {
        return element.codeMirrorLink.getValue();
    }

}

在 c# 方面,我将 ElementReference 传递给文本区域。我坚持那个引用,当我想要 CodeMirror 对象的代码时,我在我已经引用的 TextArea 中找到它。这也很好地将 CodeMirror 对象的生命周期与它正在遮蔽的文本区域联系起来。

 private ElementReference textToEdit;
 protected override Task OnAfterRenderAsync()
  {
      return javascriptRuntime.InvokeAsync<int>("hintCodeMirrorIntegration.initialize", textToEdit,
          Context.CurrentAsset.MimeType);
  }

private async Task Save()
{
    var code = await javascriptRuntime.InvokeAsync<string>("hintCodeMirrorIntegration.getCode", textToEdit);
    //... save the result in the database
}
于 2019-08-27T06:20:32.627 回答
0

不,这(还)不可能。看这里

您可以做的是全局注册您的 javascript 对象并将该引用用于最终的第二次使用。像这样:

Blazor.registerFunction('BlazorExt.CodeMirrorSetupExt', (element) =>
{
  window.mybject = CodeMirror.fromTextArea(element,
  {
     mode: 'application/ld+json',
     matchBrackets: true,
     autoCloseBrackets: true,
     indentWithTabs: true,
     lineNumbers: true,
     autofocus: true,
     styleActiveLine: true,
     readOnly: false,
     autoCloseBrackets: true,
     foldGutter: true,
     height: 'auto',
     width: 'auto',
     gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter']
   });
   return true;
 });

public static void CodeMirrorSetupExt(this ElementRef elementRef)
{
    RegisteredFunction.Invoke<bool>("BlazorExt.CodeMirrorSetupExt", elementRef);
}

接着:

  Blazor.registerFunction('BlazorExt.CodeMirrorUpdateExt', (element, Value)=>{
    window.myObject.getDoc().setValue(Value);
});

当然,您可以使用数组和键作为参考来使它更好。

于 2018-05-15T05:15:56.787 回答