- ABP Framework version: v4.2.2
- UI type: Angular / MVC / Blazor
- DB provider: EF Core / MongoDB
- Tiered (MVC) or Identity Server Separated (Angular): yes / no
- Exception message and stack trace:
- Steps to reproduce the issue:
Hi, I am implemeting my first CRUD using AbpCrudPageBase class. I have two questions about that:
- Is it allways required having two MODAL markup and repeat the fields? If the Create and Edit modal are exactly the same, do I need to repeat that? 
- In events onChange, I have two variables, NewEntity and EditingEntity. How I know if I am editing or creating a new record? The only way that I've found to resolve that was creating two different events and then duplicating code or creating a third method and pass the EntityDto as parameter. 
For example, to load an image in the event <FileEdit Changed="">, I did the code below. Is there a better way to do that?
protected async Task OnChangedLogoNew(FileChangedEventArgs e)
{
    await ChangedLogo(e, NewEntity);
}
protected async Task OnChangedLogoEditing(FileChangedEventArgs e)
{
    await ChangedLogo(e, EditingEntity);
}
protected async Task ChangedLogo(FileChangedEventArgs e, CreateUpdateSupplyNetworkDto currentDto)
{
    try
    {
        foreach (var file in e.Files)
        {
            // A stream is going to be the destination stream we're writing to.
            using (var stream = new MemoryStream())
            {
                await file.WriteToStreamAsync(stream);
                stream.Seek(0, SeekOrigin.Begin);
                currentDto.Logo = stream.ToArray();
            }
        }
    }
    catch (Exception exc)
    {
        Console.WriteLine(exc.Message);
    }
    finally
    {
        this.StateHasChanged();
    }
}
2 Answer(s)
- 
    0Hi, - In our current implementation of AbpCrudPageBaseit is required to have two modals for new and edit operations. If you don't want to make too much duplicate code you can optimize it a little by creating a new wrapper component for the modal fields. eg
 Create a component named UserFields.razor <Validation MessageLocalizer="@LH.Localize"> <Field> <FieldLabel>@L["DisplayName:Name"]</FieldLabel> <TextEdit @bind-Text="Entity.Name"> <Feedback> <ValidationError /> </Feedback> </TextEdit> </Field> </Validation> <Validation MessageLocalizer="@LH.Localize"> <Field> <FieldLabel>@L["DisplayName:Surname"]</FieldLabel> <TextEdit @bind-Text="Entity.Surname"> <Feedback> <ValidationError /> </Feedback> </TextEdit> </Field> </Validation> @code{ [Parameter] public IdentityUserCreateOrUpdateDtoBase Entity { get; set; } }And in modals pass it an entity reference <Modal @ref="CreateModal"> <ModalBackdrop /> <ModalContent Centered="true"> <Form> <ModalHeader> <ModalTitle>@L["NewUser"]</ModalTitle> <CloseButton Clicked="CloseCreateModalAsync" /> </ModalHeader> <ModalBody> <Validations @ref="@CreateValidationsRef" Model="@NewEntity" ValidateOnLoad="false"> <UserFields Entity="@NewEntity" /> </Validations> </ModalBody> <ModalFooter> <Button Color="Color.Secondary" Clicked="CloseCreateModalAsync">@L["Cancel"]</Button> <SubmitButton Clicked="@CreateEntityAsync" /> </ModalFooter> </Form> </ModalContent> </Modal>The same can be done for edit modal. 
 - You can distinguish New from Editing operation when you click on the New or Edit buttons.
 For example , create an enum Operation { Create, Edit }and overrideOpenCreateModalAsyncandOpenEditModalAsyncto set your variableoperation = Operation.Createoroperation = Operation.Edit.That way you can decide which entity to change. Regarding your final question for FileEdit, it looks good. That is how it is meant to be used. 
- In our current implementation of 
- 
    0Ok, I got it. Thank you! 
 
                                