【问题标题】:Can ElementRef property be set to a javascript interop return value in Blazor?ElementRef 属性可以设置为 Blazor 中的 javascript 互操作返回值吗?
【发布时间】:2018-05-14 22:24:59
【问题描述】:

我正在修改文本区域元素上的 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: 无法读取属性 'getDoc' of null

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

【问题讨论】:

    标签: c# asp.net-core blazor


    【解决方案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
    }
    

    【讨论】:

      【解决方案2】:

      不,这(还)不可能。 See here

      您可以做的是全局注册您的 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);
      });
      

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

      【讨论】:

      • 感谢您的回复。你能详细说明如何使用数组和键使它变得更好吗?
      • 嗯,这种快速而肮脏的解决方案只允许一个对象,这并不理想。您应该使 window.myObject 成为一个数组,并使用随机键或其他东西推送对象,同时将键返回给 C#。第二个互操作方法应该通过该键在数组中再次找到它。或者只是等待 ;-) Steve 承诺会在平台中提供一些内置功能
      猜你喜欢
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多