How to call a components public method from its parent?










1














So I want to call the OpenModal() method in the child component (TimeEntryForm). I would think I need to access the instance of TimeEntryForm component, but I don't know how to create a named instance of TimeEntryForm.



Any help would be appreciated.



Parent Component



<button type="button" onclick="@TimeEntryForm.OpenModal()" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

<TimeEntryForm></TimeEntryForm>


TimeEntry Child Component



@using Chopper.Shared
@using DatabaseModel.Models
@page "/timeentryform"
@inject HttpClient HTTP
@inherits TimeEntryFormModel

@if (IsOpened)

<div class="modal" role="dialog" tabindex="-1" style="display: block;">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add a Time Entry</h5>
</div>
<div class="modal-body">

<form>
<div class="form-group">
<label for="Job" class="col-form-label">Job:</label>
<input type="text" class="form-control" />
</div>
<div class="form-group">
<label for="Employee" class="col-form-label">Employee:</label>
<input class="form-control" type="text" />
</div>
<div class="form-group">
<label for="Hours" class="col-form-label">Hours:</label>
<input class="form-control" type="text" />
</div>
</form>

</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclickAsync="@OnAddTimeEntry()">Add Entry</button>
<button type="button" class="btn btn-primary" onclick="@CloseModal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop show"></div>



Time Entry Child Component code behind view model



using Chopper.Client.TimeEntries.Services;
using DatabaseModel.Models;
using Microsoft.AspNetCore.Blazor.Components;
using System.Threading.Tasks;

namespace Chopper.Client.TimeEntries

public class TimeEntryFormModel : BlazorComponent

protected TimeEntry TimeEntry = new TimeEntry();

[Inject]
private TimeEntriesServices _client get; set;

protected bool IsOpened get; set;

public void OpenModal()

IsOpened = true;
StateHasChanged();


//[Parameter]
protected void CloseModal()

IsOpened = false;
StateHasChanged();


protected async Task OnAddTimeEntry()


if (TimeEntry.Job != null && TimeEntry.Category != null && TimeEntry.TimeSpentHours > 0 && TimeEntry.Employee != null)

await _client.CreateTimeEntry(TimeEntry);
await OnInitAsync();
StateHasChanged();
//return true;

//return false;













share|improve this question

















  • 1




    Are you trying to capture a reference to the component so you can invoke its methods in your code?
    – Kirk Woll
    Nov 11 at 21:04















1














So I want to call the OpenModal() method in the child component (TimeEntryForm). I would think I need to access the instance of TimeEntryForm component, but I don't know how to create a named instance of TimeEntryForm.



Any help would be appreciated.



Parent Component



<button type="button" onclick="@TimeEntryForm.OpenModal()" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

<TimeEntryForm></TimeEntryForm>


TimeEntry Child Component



@using Chopper.Shared
@using DatabaseModel.Models
@page "/timeentryform"
@inject HttpClient HTTP
@inherits TimeEntryFormModel

@if (IsOpened)

<div class="modal" role="dialog" tabindex="-1" style="display: block;">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add a Time Entry</h5>
</div>
<div class="modal-body">

<form>
<div class="form-group">
<label for="Job" class="col-form-label">Job:</label>
<input type="text" class="form-control" />
</div>
<div class="form-group">
<label for="Employee" class="col-form-label">Employee:</label>
<input class="form-control" type="text" />
</div>
<div class="form-group">
<label for="Hours" class="col-form-label">Hours:</label>
<input class="form-control" type="text" />
</div>
</form>

</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclickAsync="@OnAddTimeEntry()">Add Entry</button>
<button type="button" class="btn btn-primary" onclick="@CloseModal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop show"></div>



Time Entry Child Component code behind view model



using Chopper.Client.TimeEntries.Services;
using DatabaseModel.Models;
using Microsoft.AspNetCore.Blazor.Components;
using System.Threading.Tasks;

namespace Chopper.Client.TimeEntries

public class TimeEntryFormModel : BlazorComponent

protected TimeEntry TimeEntry = new TimeEntry();

[Inject]
private TimeEntriesServices _client get; set;

protected bool IsOpened get; set;

public void OpenModal()

IsOpened = true;
StateHasChanged();


//[Parameter]
protected void CloseModal()

IsOpened = false;
StateHasChanged();


protected async Task OnAddTimeEntry()


if (TimeEntry.Job != null && TimeEntry.Category != null && TimeEntry.TimeSpentHours > 0 && TimeEntry.Employee != null)

await _client.CreateTimeEntry(TimeEntry);
await OnInitAsync();
StateHasChanged();
//return true;

//return false;













share|improve this question

















  • 1




    Are you trying to capture a reference to the component so you can invoke its methods in your code?
    – Kirk Woll
    Nov 11 at 21:04













1












1








1







So I want to call the OpenModal() method in the child component (TimeEntryForm). I would think I need to access the instance of TimeEntryForm component, but I don't know how to create a named instance of TimeEntryForm.



Any help would be appreciated.



Parent Component



<button type="button" onclick="@TimeEntryForm.OpenModal()" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

<TimeEntryForm></TimeEntryForm>


TimeEntry Child Component



@using Chopper.Shared
@using DatabaseModel.Models
@page "/timeentryform"
@inject HttpClient HTTP
@inherits TimeEntryFormModel

@if (IsOpened)

<div class="modal" role="dialog" tabindex="-1" style="display: block;">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add a Time Entry</h5>
</div>
<div class="modal-body">

<form>
<div class="form-group">
<label for="Job" class="col-form-label">Job:</label>
<input type="text" class="form-control" />
</div>
<div class="form-group">
<label for="Employee" class="col-form-label">Employee:</label>
<input class="form-control" type="text" />
</div>
<div class="form-group">
<label for="Hours" class="col-form-label">Hours:</label>
<input class="form-control" type="text" />
</div>
</form>

</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclickAsync="@OnAddTimeEntry()">Add Entry</button>
<button type="button" class="btn btn-primary" onclick="@CloseModal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop show"></div>



Time Entry Child Component code behind view model



using Chopper.Client.TimeEntries.Services;
using DatabaseModel.Models;
using Microsoft.AspNetCore.Blazor.Components;
using System.Threading.Tasks;

namespace Chopper.Client.TimeEntries

public class TimeEntryFormModel : BlazorComponent

protected TimeEntry TimeEntry = new TimeEntry();

[Inject]
private TimeEntriesServices _client get; set;

protected bool IsOpened get; set;

public void OpenModal()

IsOpened = true;
StateHasChanged();


//[Parameter]
protected void CloseModal()

IsOpened = false;
StateHasChanged();


protected async Task OnAddTimeEntry()


if (TimeEntry.Job != null && TimeEntry.Category != null && TimeEntry.TimeSpentHours > 0 && TimeEntry.Employee != null)

await _client.CreateTimeEntry(TimeEntry);
await OnInitAsync();
StateHasChanged();
//return true;

//return false;













share|improve this question













So I want to call the OpenModal() method in the child component (TimeEntryForm). I would think I need to access the instance of TimeEntryForm component, but I don't know how to create a named instance of TimeEntryForm.



Any help would be appreciated.



Parent Component



<button type="button" onclick="@TimeEntryForm.OpenModal()" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

<TimeEntryForm></TimeEntryForm>


TimeEntry Child Component



@using Chopper.Shared
@using DatabaseModel.Models
@page "/timeentryform"
@inject HttpClient HTTP
@inherits TimeEntryFormModel

@if (IsOpened)

<div class="modal" role="dialog" tabindex="-1" style="display: block;">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add a Time Entry</h5>
</div>
<div class="modal-body">

<form>
<div class="form-group">
<label for="Job" class="col-form-label">Job:</label>
<input type="text" class="form-control" />
</div>
<div class="form-group">
<label for="Employee" class="col-form-label">Employee:</label>
<input class="form-control" type="text" />
</div>
<div class="form-group">
<label for="Hours" class="col-form-label">Hours:</label>
<input class="form-control" type="text" />
</div>
</form>

</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclickAsync="@OnAddTimeEntry()">Add Entry</button>
<button type="button" class="btn btn-primary" onclick="@CloseModal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop show"></div>



Time Entry Child Component code behind view model



using Chopper.Client.TimeEntries.Services;
using DatabaseModel.Models;
using Microsoft.AspNetCore.Blazor.Components;
using System.Threading.Tasks;

namespace Chopper.Client.TimeEntries

public class TimeEntryFormModel : BlazorComponent

protected TimeEntry TimeEntry = new TimeEntry();

[Inject]
private TimeEntriesServices _client get; set;

protected bool IsOpened get; set;

public void OpenModal()

IsOpened = true;
StateHasChanged();


//[Parameter]
protected void CloseModal()

IsOpened = false;
StateHasChanged();


protected async Task OnAddTimeEntry()


if (TimeEntry.Job != null && TimeEntry.Category != null && TimeEntry.TimeSpentHours > 0 && TimeEntry.Employee != null)

await _client.CreateTimeEntry(TimeEntry);
await OnInitAsync();
StateHasChanged();
//return true;

//return false;










blazor






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 19:03









TheColonel26

7812934




7812934







  • 1




    Are you trying to capture a reference to the component so you can invoke its methods in your code?
    – Kirk Woll
    Nov 11 at 21:04












  • 1




    Are you trying to capture a reference to the component so you can invoke its methods in your code?
    – Kirk Woll
    Nov 11 at 21:04







1




1




Are you trying to capture a reference to the component so you can invoke its methods in your code?
– Kirk Woll
Nov 11 at 21:04




Are you trying to capture a reference to the component so you can invoke its methods in your code?
– Kirk Woll
Nov 11 at 21:04












2 Answers
2






active

oldest

votes


















1














So I needed to add a protected member in the parent component model of protected TimeEntryForm timeEntryForm = new TimeEntryForm();



and then do a reference to it in the view as <TimeEntryForm ref="timeEntryForm"></TimeEntryForm>



Parent Component



<button type="button" onclick="@timeEntryForm.OpenModal()" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

<TimeEntryForm ref="timeEntryForm"></TimeEntryForm>


Parent Component code behind model/viewmodel



public class TimeEntriesGridModel : BlazorComponent

[Inject]
private TimeEntriesServices _client get; set;

protected TimeEntryForm timeEntryForm; // = new TimeEntryForm(); //Per Kirk Woll's suggestion

protected List<TimeEntry> Model get; set;

protected override async Task OnInitAsync()

Model = await _client.GetAllTimeEntries();






TimeEntry Child Component



@using Chopper.Shared
@using DatabaseModel.Models
@page "/timeentryform"
@inject HttpClient HTTP
@inherits TimeEntryFormModel

@if (IsOpened)

<div class="modal" role="dialog" tabindex="-1" style="display: block;">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add a Time Entry</h5>
</div>
<div class="modal-body">

<form>
<div class="form-group">
<label for="Job" class="col-form-label">Job:</label>
<input type="text" class="form-control" />
</div>
<div class="form-group">
<label for="Employee" class="col-form-label">Employee:</label>
<input class="form-control" type="text" />
</div>
<div class="form-group">
<label for="Hours" class="col-form-label">Hours:</label>
<input class="form-control" type="text" />
</div>
</form>

</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclickAsync="@OnAddTimeEntry()">Add Entry</button>
<button type="button" class="btn btn-primary" onclick="@CloseModal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop show"></div>



Time Entry Child Component code behind view model



using Chopper.Client.TimeEntries.Services;
using DatabaseModel.Models;
using Microsoft.AspNetCore.Blazor.Components;
using System.Threading.Tasks;

namespace Chopper.Client.TimeEntries

public class TimeEntryFormModel : BlazorComponent

protected TimeEntry TimeEntry = new TimeEntry();

[Inject]
private TimeEntriesServices _client get; set;

protected bool IsOpened get; set;

public void OpenModal()

IsOpened = true;
StateHasChanged();


//[Parameter]
protected void CloseModal()

IsOpened = false;
StateHasChanged();


protected async Task OnAddTimeEntry()


if (TimeEntry.Job != null && TimeEntry.Category != null && TimeEntry.TimeSpentHours > 0 && TimeEntry.Employee != null)

await _client.CreateTimeEntry(TimeEntry);
await OnInitAsync();
StateHasChanged();
//return true;

//return false;






EIA:



Removed code behind initialization for timeEntryForm per Kirk Woll's suggestion.






share|improve this answer


















  • 1




    The line, protected TimeEntryForm timeEntryForm = new TimeEntryForm(); I don't think you ought to initialize it. It's probably not breaking anything (right now) but it's probably wrong. The instance should be initialized via your ref="timeEntryForm" attribute. That will make it (eventually) not null. If you use it earlier (when it's not null due to your initializer) it will, I suspect, potentially lead to surprising bugs in the future.
    – Kirk Woll
    Nov 11 at 22:39










  • Captain, What do you do with this: protected TimeEntryForm timeEntryForm; // = new TimeEntryForm(); //Per Kirk Woll's suggestion ? OK, you've got a reference to the child component stored in the variable timeEntryForm, what do you do with it ? Where do you use it ?
    – Issac
    Nov 11 at 23:59











  • I don't need to use it anywhere, at least so far, except to call OpenModal.
    – TheColonel26
    Nov 12 at 0:46


















0














Comrade,
Please, follow these steps:
1. Define in the Parent Component an event delegate whose object is to tell the child
component to open the modal window:

public event Action OnOpenModal;

2. Define in the Parent Component a method that invokes the event delegate

private void OpenMe() => OnOpenModal?.Invoke();

3. This method is called when the user click the button defined in the Parent Component:
Note: Do not use parentheses after OpenMe

<button type="button" onclick="@OpenMe" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

4. Add a property MyModal to the Child Component element with the value of the event delegate

<TimeEntryForm MyModal = "@OnOpenModal"></TimeEntryForm>



 Define a property of Action delegate to store the event delegate passed to the Child Component




[Parameter] protected Action MyModal get; set;


protected override void OnInit()

// Attach the OpenModal method defined in the Child // Component to the delegate
MyModal += OpenModal;


Now, whenever the user hit the button the OpenModal is called and the modal window
is displayed.

public void OpenModal()



IsOpened = true;
StateHasChanged();






share|improve this answer




















  • Why do I need to define a method and a Action delegate in the parent and a method, and Action Delegate in the child when I can just have the parent call the child method directly? what is the advantage to the is 3 extra method?
    – TheColonel26
    Nov 12 at 1:39










  • This code does not work you cannot subscribe to MyModal with OpenModal
    – TheColonel26
    Nov 26 at 17:54










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53252160%2fhow-to-call-a-components-public-method-from-its-parent%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














So I needed to add a protected member in the parent component model of protected TimeEntryForm timeEntryForm = new TimeEntryForm();



and then do a reference to it in the view as <TimeEntryForm ref="timeEntryForm"></TimeEntryForm>



Parent Component



<button type="button" onclick="@timeEntryForm.OpenModal()" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

<TimeEntryForm ref="timeEntryForm"></TimeEntryForm>


Parent Component code behind model/viewmodel



public class TimeEntriesGridModel : BlazorComponent

[Inject]
private TimeEntriesServices _client get; set;

protected TimeEntryForm timeEntryForm; // = new TimeEntryForm(); //Per Kirk Woll's suggestion

protected List<TimeEntry> Model get; set;

protected override async Task OnInitAsync()

Model = await _client.GetAllTimeEntries();






TimeEntry Child Component



@using Chopper.Shared
@using DatabaseModel.Models
@page "/timeentryform"
@inject HttpClient HTTP
@inherits TimeEntryFormModel

@if (IsOpened)

<div class="modal" role="dialog" tabindex="-1" style="display: block;">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add a Time Entry</h5>
</div>
<div class="modal-body">

<form>
<div class="form-group">
<label for="Job" class="col-form-label">Job:</label>
<input type="text" class="form-control" />
</div>
<div class="form-group">
<label for="Employee" class="col-form-label">Employee:</label>
<input class="form-control" type="text" />
</div>
<div class="form-group">
<label for="Hours" class="col-form-label">Hours:</label>
<input class="form-control" type="text" />
</div>
</form>

</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclickAsync="@OnAddTimeEntry()">Add Entry</button>
<button type="button" class="btn btn-primary" onclick="@CloseModal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop show"></div>



Time Entry Child Component code behind view model



using Chopper.Client.TimeEntries.Services;
using DatabaseModel.Models;
using Microsoft.AspNetCore.Blazor.Components;
using System.Threading.Tasks;

namespace Chopper.Client.TimeEntries

public class TimeEntryFormModel : BlazorComponent

protected TimeEntry TimeEntry = new TimeEntry();

[Inject]
private TimeEntriesServices _client get; set;

protected bool IsOpened get; set;

public void OpenModal()

IsOpened = true;
StateHasChanged();


//[Parameter]
protected void CloseModal()

IsOpened = false;
StateHasChanged();


protected async Task OnAddTimeEntry()


if (TimeEntry.Job != null && TimeEntry.Category != null && TimeEntry.TimeSpentHours > 0 && TimeEntry.Employee != null)

await _client.CreateTimeEntry(TimeEntry);
await OnInitAsync();
StateHasChanged();
//return true;

//return false;






EIA:



Removed code behind initialization for timeEntryForm per Kirk Woll's suggestion.






share|improve this answer


















  • 1




    The line, protected TimeEntryForm timeEntryForm = new TimeEntryForm(); I don't think you ought to initialize it. It's probably not breaking anything (right now) but it's probably wrong. The instance should be initialized via your ref="timeEntryForm" attribute. That will make it (eventually) not null. If you use it earlier (when it's not null due to your initializer) it will, I suspect, potentially lead to surprising bugs in the future.
    – Kirk Woll
    Nov 11 at 22:39










  • Captain, What do you do with this: protected TimeEntryForm timeEntryForm; // = new TimeEntryForm(); //Per Kirk Woll's suggestion ? OK, you've got a reference to the child component stored in the variable timeEntryForm, what do you do with it ? Where do you use it ?
    – Issac
    Nov 11 at 23:59











  • I don't need to use it anywhere, at least so far, except to call OpenModal.
    – TheColonel26
    Nov 12 at 0:46















1














So I needed to add a protected member in the parent component model of protected TimeEntryForm timeEntryForm = new TimeEntryForm();



and then do a reference to it in the view as <TimeEntryForm ref="timeEntryForm"></TimeEntryForm>



Parent Component



<button type="button" onclick="@timeEntryForm.OpenModal()" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

<TimeEntryForm ref="timeEntryForm"></TimeEntryForm>


Parent Component code behind model/viewmodel



public class TimeEntriesGridModel : BlazorComponent

[Inject]
private TimeEntriesServices _client get; set;

protected TimeEntryForm timeEntryForm; // = new TimeEntryForm(); //Per Kirk Woll's suggestion

protected List<TimeEntry> Model get; set;

protected override async Task OnInitAsync()

Model = await _client.GetAllTimeEntries();






TimeEntry Child Component



@using Chopper.Shared
@using DatabaseModel.Models
@page "/timeentryform"
@inject HttpClient HTTP
@inherits TimeEntryFormModel

@if (IsOpened)

<div class="modal" role="dialog" tabindex="-1" style="display: block;">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add a Time Entry</h5>
</div>
<div class="modal-body">

<form>
<div class="form-group">
<label for="Job" class="col-form-label">Job:</label>
<input type="text" class="form-control" />
</div>
<div class="form-group">
<label for="Employee" class="col-form-label">Employee:</label>
<input class="form-control" type="text" />
</div>
<div class="form-group">
<label for="Hours" class="col-form-label">Hours:</label>
<input class="form-control" type="text" />
</div>
</form>

</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclickAsync="@OnAddTimeEntry()">Add Entry</button>
<button type="button" class="btn btn-primary" onclick="@CloseModal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop show"></div>



Time Entry Child Component code behind view model



using Chopper.Client.TimeEntries.Services;
using DatabaseModel.Models;
using Microsoft.AspNetCore.Blazor.Components;
using System.Threading.Tasks;

namespace Chopper.Client.TimeEntries

public class TimeEntryFormModel : BlazorComponent

protected TimeEntry TimeEntry = new TimeEntry();

[Inject]
private TimeEntriesServices _client get; set;

protected bool IsOpened get; set;

public void OpenModal()

IsOpened = true;
StateHasChanged();


//[Parameter]
protected void CloseModal()

IsOpened = false;
StateHasChanged();


protected async Task OnAddTimeEntry()


if (TimeEntry.Job != null && TimeEntry.Category != null && TimeEntry.TimeSpentHours > 0 && TimeEntry.Employee != null)

await _client.CreateTimeEntry(TimeEntry);
await OnInitAsync();
StateHasChanged();
//return true;

//return false;






EIA:



Removed code behind initialization for timeEntryForm per Kirk Woll's suggestion.






share|improve this answer


















  • 1




    The line, protected TimeEntryForm timeEntryForm = new TimeEntryForm(); I don't think you ought to initialize it. It's probably not breaking anything (right now) but it's probably wrong. The instance should be initialized via your ref="timeEntryForm" attribute. That will make it (eventually) not null. If you use it earlier (when it's not null due to your initializer) it will, I suspect, potentially lead to surprising bugs in the future.
    – Kirk Woll
    Nov 11 at 22:39










  • Captain, What do you do with this: protected TimeEntryForm timeEntryForm; // = new TimeEntryForm(); //Per Kirk Woll's suggestion ? OK, you've got a reference to the child component stored in the variable timeEntryForm, what do you do with it ? Where do you use it ?
    – Issac
    Nov 11 at 23:59











  • I don't need to use it anywhere, at least so far, except to call OpenModal.
    – TheColonel26
    Nov 12 at 0:46













1












1








1






So I needed to add a protected member in the parent component model of protected TimeEntryForm timeEntryForm = new TimeEntryForm();



and then do a reference to it in the view as <TimeEntryForm ref="timeEntryForm"></TimeEntryForm>



Parent Component



<button type="button" onclick="@timeEntryForm.OpenModal()" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

<TimeEntryForm ref="timeEntryForm"></TimeEntryForm>


Parent Component code behind model/viewmodel



public class TimeEntriesGridModel : BlazorComponent

[Inject]
private TimeEntriesServices _client get; set;

protected TimeEntryForm timeEntryForm; // = new TimeEntryForm(); //Per Kirk Woll's suggestion

protected List<TimeEntry> Model get; set;

protected override async Task OnInitAsync()

Model = await _client.GetAllTimeEntries();






TimeEntry Child Component



@using Chopper.Shared
@using DatabaseModel.Models
@page "/timeentryform"
@inject HttpClient HTTP
@inherits TimeEntryFormModel

@if (IsOpened)

<div class="modal" role="dialog" tabindex="-1" style="display: block;">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add a Time Entry</h5>
</div>
<div class="modal-body">

<form>
<div class="form-group">
<label for="Job" class="col-form-label">Job:</label>
<input type="text" class="form-control" />
</div>
<div class="form-group">
<label for="Employee" class="col-form-label">Employee:</label>
<input class="form-control" type="text" />
</div>
<div class="form-group">
<label for="Hours" class="col-form-label">Hours:</label>
<input class="form-control" type="text" />
</div>
</form>

</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclickAsync="@OnAddTimeEntry()">Add Entry</button>
<button type="button" class="btn btn-primary" onclick="@CloseModal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop show"></div>



Time Entry Child Component code behind view model



using Chopper.Client.TimeEntries.Services;
using DatabaseModel.Models;
using Microsoft.AspNetCore.Blazor.Components;
using System.Threading.Tasks;

namespace Chopper.Client.TimeEntries

public class TimeEntryFormModel : BlazorComponent

protected TimeEntry TimeEntry = new TimeEntry();

[Inject]
private TimeEntriesServices _client get; set;

protected bool IsOpened get; set;

public void OpenModal()

IsOpened = true;
StateHasChanged();


//[Parameter]
protected void CloseModal()

IsOpened = false;
StateHasChanged();


protected async Task OnAddTimeEntry()


if (TimeEntry.Job != null && TimeEntry.Category != null && TimeEntry.TimeSpentHours > 0 && TimeEntry.Employee != null)

await _client.CreateTimeEntry(TimeEntry);
await OnInitAsync();
StateHasChanged();
//return true;

//return false;






EIA:



Removed code behind initialization for timeEntryForm per Kirk Woll's suggestion.






share|improve this answer














So I needed to add a protected member in the parent component model of protected TimeEntryForm timeEntryForm = new TimeEntryForm();



and then do a reference to it in the view as <TimeEntryForm ref="timeEntryForm"></TimeEntryForm>



Parent Component



<button type="button" onclick="@timeEntryForm.OpenModal()" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

<TimeEntryForm ref="timeEntryForm"></TimeEntryForm>


Parent Component code behind model/viewmodel



public class TimeEntriesGridModel : BlazorComponent

[Inject]
private TimeEntriesServices _client get; set;

protected TimeEntryForm timeEntryForm; // = new TimeEntryForm(); //Per Kirk Woll's suggestion

protected List<TimeEntry> Model get; set;

protected override async Task OnInitAsync()

Model = await _client.GetAllTimeEntries();






TimeEntry Child Component



@using Chopper.Shared
@using DatabaseModel.Models
@page "/timeentryform"
@inject HttpClient HTTP
@inherits TimeEntryFormModel

@if (IsOpened)

<div class="modal" role="dialog" tabindex="-1" style="display: block;">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add a Time Entry</h5>
</div>
<div class="modal-body">

<form>
<div class="form-group">
<label for="Job" class="col-form-label">Job:</label>
<input type="text" class="form-control" />
</div>
<div class="form-group">
<label for="Employee" class="col-form-label">Employee:</label>
<input class="form-control" type="text" />
</div>
<div class="form-group">
<label for="Hours" class="col-form-label">Hours:</label>
<input class="form-control" type="text" />
</div>
</form>

</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclickAsync="@OnAddTimeEntry()">Add Entry</button>
<button type="button" class="btn btn-primary" onclick="@CloseModal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal-backdrop show"></div>



Time Entry Child Component code behind view model



using Chopper.Client.TimeEntries.Services;
using DatabaseModel.Models;
using Microsoft.AspNetCore.Blazor.Components;
using System.Threading.Tasks;

namespace Chopper.Client.TimeEntries

public class TimeEntryFormModel : BlazorComponent

protected TimeEntry TimeEntry = new TimeEntry();

[Inject]
private TimeEntriesServices _client get; set;

protected bool IsOpened get; set;

public void OpenModal()

IsOpened = true;
StateHasChanged();


//[Parameter]
protected void CloseModal()

IsOpened = false;
StateHasChanged();


protected async Task OnAddTimeEntry()


if (TimeEntry.Job != null && TimeEntry.Category != null && TimeEntry.TimeSpentHours > 0 && TimeEntry.Employee != null)

await _client.CreateTimeEntry(TimeEntry);
await OnInitAsync();
StateHasChanged();
//return true;

//return false;






EIA:



Removed code behind initialization for timeEntryForm per Kirk Woll's suggestion.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 12 at 1:41

























answered Nov 11 at 21:43









TheColonel26

7812934




7812934







  • 1




    The line, protected TimeEntryForm timeEntryForm = new TimeEntryForm(); I don't think you ought to initialize it. It's probably not breaking anything (right now) but it's probably wrong. The instance should be initialized via your ref="timeEntryForm" attribute. That will make it (eventually) not null. If you use it earlier (when it's not null due to your initializer) it will, I suspect, potentially lead to surprising bugs in the future.
    – Kirk Woll
    Nov 11 at 22:39










  • Captain, What do you do with this: protected TimeEntryForm timeEntryForm; // = new TimeEntryForm(); //Per Kirk Woll's suggestion ? OK, you've got a reference to the child component stored in the variable timeEntryForm, what do you do with it ? Where do you use it ?
    – Issac
    Nov 11 at 23:59











  • I don't need to use it anywhere, at least so far, except to call OpenModal.
    – TheColonel26
    Nov 12 at 0:46












  • 1




    The line, protected TimeEntryForm timeEntryForm = new TimeEntryForm(); I don't think you ought to initialize it. It's probably not breaking anything (right now) but it's probably wrong. The instance should be initialized via your ref="timeEntryForm" attribute. That will make it (eventually) not null. If you use it earlier (when it's not null due to your initializer) it will, I suspect, potentially lead to surprising bugs in the future.
    – Kirk Woll
    Nov 11 at 22:39










  • Captain, What do you do with this: protected TimeEntryForm timeEntryForm; // = new TimeEntryForm(); //Per Kirk Woll's suggestion ? OK, you've got a reference to the child component stored in the variable timeEntryForm, what do you do with it ? Where do you use it ?
    – Issac
    Nov 11 at 23:59











  • I don't need to use it anywhere, at least so far, except to call OpenModal.
    – TheColonel26
    Nov 12 at 0:46







1




1




The line, protected TimeEntryForm timeEntryForm = new TimeEntryForm(); I don't think you ought to initialize it. It's probably not breaking anything (right now) but it's probably wrong. The instance should be initialized via your ref="timeEntryForm" attribute. That will make it (eventually) not null. If you use it earlier (when it's not null due to your initializer) it will, I suspect, potentially lead to surprising bugs in the future.
– Kirk Woll
Nov 11 at 22:39




The line, protected TimeEntryForm timeEntryForm = new TimeEntryForm(); I don't think you ought to initialize it. It's probably not breaking anything (right now) but it's probably wrong. The instance should be initialized via your ref="timeEntryForm" attribute. That will make it (eventually) not null. If you use it earlier (when it's not null due to your initializer) it will, I suspect, potentially lead to surprising bugs in the future.
– Kirk Woll
Nov 11 at 22:39












Captain, What do you do with this: protected TimeEntryForm timeEntryForm; // = new TimeEntryForm(); //Per Kirk Woll's suggestion ? OK, you've got a reference to the child component stored in the variable timeEntryForm, what do you do with it ? Where do you use it ?
– Issac
Nov 11 at 23:59





Captain, What do you do with this: protected TimeEntryForm timeEntryForm; // = new TimeEntryForm(); //Per Kirk Woll's suggestion ? OK, you've got a reference to the child component stored in the variable timeEntryForm, what do you do with it ? Where do you use it ?
– Issac
Nov 11 at 23:59













I don't need to use it anywhere, at least so far, except to call OpenModal.
– TheColonel26
Nov 12 at 0:46




I don't need to use it anywhere, at least so far, except to call OpenModal.
– TheColonel26
Nov 12 at 0:46













0














Comrade,
Please, follow these steps:
1. Define in the Parent Component an event delegate whose object is to tell the child
component to open the modal window:

public event Action OnOpenModal;

2. Define in the Parent Component a method that invokes the event delegate

private void OpenMe() => OnOpenModal?.Invoke();

3. This method is called when the user click the button defined in the Parent Component:
Note: Do not use parentheses after OpenMe

<button type="button" onclick="@OpenMe" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

4. Add a property MyModal to the Child Component element with the value of the event delegate

<TimeEntryForm MyModal = "@OnOpenModal"></TimeEntryForm>



 Define a property of Action delegate to store the event delegate passed to the Child Component




[Parameter] protected Action MyModal get; set;


protected override void OnInit()

// Attach the OpenModal method defined in the Child // Component to the delegate
MyModal += OpenModal;


Now, whenever the user hit the button the OpenModal is called and the modal window
is displayed.

public void OpenModal()



IsOpened = true;
StateHasChanged();






share|improve this answer




















  • Why do I need to define a method and a Action delegate in the parent and a method, and Action Delegate in the child when I can just have the parent call the child method directly? what is the advantage to the is 3 extra method?
    – TheColonel26
    Nov 12 at 1:39










  • This code does not work you cannot subscribe to MyModal with OpenModal
    – TheColonel26
    Nov 26 at 17:54















0














Comrade,
Please, follow these steps:
1. Define in the Parent Component an event delegate whose object is to tell the child
component to open the modal window:

public event Action OnOpenModal;

2. Define in the Parent Component a method that invokes the event delegate

private void OpenMe() => OnOpenModal?.Invoke();

3. This method is called when the user click the button defined in the Parent Component:
Note: Do not use parentheses after OpenMe

<button type="button" onclick="@OpenMe" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

4. Add a property MyModal to the Child Component element with the value of the event delegate

<TimeEntryForm MyModal = "@OnOpenModal"></TimeEntryForm>



 Define a property of Action delegate to store the event delegate passed to the Child Component




[Parameter] protected Action MyModal get; set;


protected override void OnInit()

// Attach the OpenModal method defined in the Child // Component to the delegate
MyModal += OpenModal;


Now, whenever the user hit the button the OpenModal is called and the modal window
is displayed.

public void OpenModal()



IsOpened = true;
StateHasChanged();






share|improve this answer




















  • Why do I need to define a method and a Action delegate in the parent and a method, and Action Delegate in the child when I can just have the parent call the child method directly? what is the advantage to the is 3 extra method?
    – TheColonel26
    Nov 12 at 1:39










  • This code does not work you cannot subscribe to MyModal with OpenModal
    – TheColonel26
    Nov 26 at 17:54













0












0








0






Comrade,
Please, follow these steps:
1. Define in the Parent Component an event delegate whose object is to tell the child
component to open the modal window:

public event Action OnOpenModal;

2. Define in the Parent Component a method that invokes the event delegate

private void OpenMe() => OnOpenModal?.Invoke();

3. This method is called when the user click the button defined in the Parent Component:
Note: Do not use parentheses after OpenMe

<button type="button" onclick="@OpenMe" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

4. Add a property MyModal to the Child Component element with the value of the event delegate

<TimeEntryForm MyModal = "@OnOpenModal"></TimeEntryForm>



 Define a property of Action delegate to store the event delegate passed to the Child Component




[Parameter] protected Action MyModal get; set;


protected override void OnInit()

// Attach the OpenModal method defined in the Child // Component to the delegate
MyModal += OpenModal;


Now, whenever the user hit the button the OpenModal is called and the modal window
is displayed.

public void OpenModal()



IsOpened = true;
StateHasChanged();






share|improve this answer












Comrade,
Please, follow these steps:
1. Define in the Parent Component an event delegate whose object is to tell the child
component to open the modal window:

public event Action OnOpenModal;

2. Define in the Parent Component a method that invokes the event delegate

private void OpenMe() => OnOpenModal?.Invoke();

3. This method is called when the user click the button defined in the Parent Component:
Note: Do not use parentheses after OpenMe

<button type="button" onclick="@OpenMe" class="btn btn-info btn-lg">
<span class="glyphicon glyphicon-plus"></span> Add
</>

4. Add a property MyModal to the Child Component element with the value of the event delegate

<TimeEntryForm MyModal = "@OnOpenModal"></TimeEntryForm>



 Define a property of Action delegate to store the event delegate passed to the Child Component




[Parameter] protected Action MyModal get; set;


protected override void OnInit()

// Attach the OpenModal method defined in the Child // Component to the delegate
MyModal += OpenModal;


Now, whenever the user hit the button the OpenModal is called and the modal window
is displayed.

public void OpenModal()



IsOpened = true;
StateHasChanged();







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 11 at 22:43









Issac

1,1271312




1,1271312











  • Why do I need to define a method and a Action delegate in the parent and a method, and Action Delegate in the child when I can just have the parent call the child method directly? what is the advantage to the is 3 extra method?
    – TheColonel26
    Nov 12 at 1:39










  • This code does not work you cannot subscribe to MyModal with OpenModal
    – TheColonel26
    Nov 26 at 17:54
















  • Why do I need to define a method and a Action delegate in the parent and a method, and Action Delegate in the child when I can just have the parent call the child method directly? what is the advantage to the is 3 extra method?
    – TheColonel26
    Nov 12 at 1:39










  • This code does not work you cannot subscribe to MyModal with OpenModal
    – TheColonel26
    Nov 26 at 17:54















Why do I need to define a method and a Action delegate in the parent and a method, and Action Delegate in the child when I can just have the parent call the child method directly? what is the advantage to the is 3 extra method?
– TheColonel26
Nov 12 at 1:39




Why do I need to define a method and a Action delegate in the parent and a method, and Action Delegate in the child when I can just have the parent call the child method directly? what is the advantage to the is 3 extra method?
– TheColonel26
Nov 12 at 1:39












This code does not work you cannot subscribe to MyModal with OpenModal
– TheColonel26
Nov 26 at 17:54




This code does not work you cannot subscribe to MyModal with OpenModal
– TheColonel26
Nov 26 at 17:54

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53252160%2fhow-to-call-a-components-public-method-from-its-parent%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Kleinkühnau

Makov (Slowakei)

Deutsches Schauspielhaus