'How to call a function in a Blazor component from a Razor page
I'm creating a MarkdownEditor component for Blazor based on EasyMDE. The project on GitHub is working apart from the file upload because I can't find a way to run a function in the component from the page.
I explain with same code because I don't know how to explain better. This is the basic code for the MarkdownEditor
in a Razor page. There are some events that I map such as ImageUploadChanged
<MarkdownEditor Value="@markdownValue" ValueChanged="@OnMarkdownValueChanged"
ImageUploadEndpoint="https://localhost:7013/api/Image"
ImageUploadChanged="@OnImageUploadChanged"
ImageUploadStarted="@OnImageUploadStarted"
ImageUploadProgressed="@OnImageUploadProgressed"
ImageUploadEnded="@OnImageUploadEnded" />
async Task OnImageUploadChanged(FileChangedEventArgs e)
{
// e contains the image to upload via API
// at the end I want to execute ImageUploadEnded
}
In the MarkdownEditor, the user can upload images. When an image is dropped on the editor, the event ImageUploadChanged
is fired from the component.
The UI has to upload the file somewhere via API. I like to show to the user the progression of the upload. So, I have to call a function in the MarkdownEditor
to update the user about the status of a specific file.
Similarly, when the upload is completed, I have to notify the MarkdownEditor
the URL of the image. So, it adds the classic string in the text. For that, I have to execute a call to the JavaScript and pass some parameters that only the component knows such as the ElementId
.
If I add a @ref="@ElementRef"
I don't have access to the public function from the component. Also, I don't want to invoke a JavaScript from the component because I think it is not very elegant.
Basically, I want to call the function notifyImageUploadSuccess
in the markdownEditor.js
(here the code)
function notifyImageUploadSuccess(elementId, imageUrl) {
const instance = _instances[elementId];
if (instance) {
return instance.imageUploadNotifier.onSuccess(imageUrl);
}
}
The UI knows only the imageUrl
and for this reason I have to pass the imageUrl
to the component and then the component has to call the JavaScript function.
I can't find a way. Maybe it is very simple.
Solution 1:[1]
In Upload.razor update [MarkdownEditor] like this line:
<MarkdownEditor @ref="markdownEditor" AutoSaveEnabled="true" AutoSaveId="UploadPage" Value="@markdownValue" ValueChanged="@OnMarkdownValueChanged" ValueHTMLChanged="@OnMarkdownValueHTMLChanged" ImageUploadEndpoint="https://localhost:7013/api/files" ImageUploadChanged="@OnImageUploadChanged" ImageUploadStarted="@OnImageUploadStarted" ImageUploadProgressed="@OnImageUploadProgressed" ImageUploadEnded="@OnImageUploadEnded" UploadImage="true" />
In same page code add:
MarkdownEditor markdownEditor { get; set; }
In same page code update this methode like this code:
async Task OnImageUploadChanged(FileChangedEventArgs e) { if (e.Files.Length > 0) await markdownEditor.NotifyImageUpload(e.Files[0]); this.StateHasChanged(); }
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | mhdcindioglu |