How to call a components public method from its parent?
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
add a comment |
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
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
add a comment |
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
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
blazor
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
add a comment |
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
add a comment |
2 Answers
2
active
oldest
votes
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.
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 yourref="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
add a comment |
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();
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
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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 yourref="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
add a comment |
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.
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 yourref="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
add a comment |
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.
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.
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 yourref="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
add a comment |
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 yourref="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
add a comment |
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();
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
add a comment |
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();
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
add a comment |
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();
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();
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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