可以在 Blazor 中将 ElementRef 属性 设置为 javascript 互操作 return 值吗?
Can ElementRef property be set to a javascript interop return value in Blazor?
我正在修改文本区域元素上的 CodeMirror。我正在使用 javascript 互操作来完成此操作,并且在应用代码镜像时它工作正常。
然而,我的意图是 return 那个 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 是不可能的?
不,这(还)不可能。 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);
});
当然,您可以使用数组和键作为参考,使它变得更好。
我扩展了@Flores 的回答。不是创建一个包含所有 javascript 对象的全局数组,而是将新值存储在一个 javascript DOM 对象中,您已经有一个 elementReference 到。
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
}
我正在修改文本区域元素上的 CodeMirror。我正在使用 javascript 互操作来完成此操作,并且在应用代码镜像时它工作正常。 然而,我的意图是 return 那个 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 是不可能的?
不,这(还)不可能。 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);
});
当然,您可以使用数组和键作为参考,使它变得更好。
我扩展了@Flores 的回答。不是创建一个包含所有 javascript 对象的全局数组,而是将新值存储在一个 javascript DOM 对象中,您已经有一个 elementReference 到。
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
}