Вызов метода в MainLayout из компонента страницы в Blazor

У меня есть приложение Blazor со страницей MainLayout, в которой есть @Body для загрузки фактического содержимого страницы.

В моем случае Index.razor загружается внутри страницы MainLayout.

Есть ли способ вызвать метод с дочерней страницы (Index.razor), который находится на родительской странице; MainLayout.razor?

Пример:

MainLayout.razor

<div class="content">
<ul class="menu">
  <li>menu item 1</li>
</ul>

@Body

</div>

@code
{
    public async Task Test()
    {
        await JsRuntime.InvokeAsync<object>("console.log", "test parent");
    }
}

Index.razor

<h1>This is the index page</h1>
<button @onclick="(async () => await btn_clicked())">Call parent method</button>

@code
{
    // Call method in MainLayout
    public async Task btn_clicked()
    {
        await parent.Test();
    }
}

person Vivendi    schedule 26.09.2019    source источник
comment
вам больше не нужна асинхронная Ламда. Вы можете просто использовать @onclick=btn_clicked   -  person Neville Nazerane    schedule 27.09.2019


Ответы (2)


Вы можете сделать это с помощью комбинации каскадных значений и EventCallback.

Сначала создайте обратный вызов события для вашего Test. Для этого добавьте следующий код в свой MainLayout.razor.

EventCallback btn_clicked => EventCallback.Factory.Create(this, Test);

Или, чтобы убедиться, что вы создаете этот объект только один раз, вы можете использовать следующее:

EventCallback _btn_clicked = EventCallback.Empty;
EventCallback btn_clicked  {
    get {
        if (_btn_clicked.Equals(EventCallback.Empty))
            _btn_clicked = EventCallback.Factory.Create(this, Test);
        return _btn_clicked;
    }
}

Затем убедитесь, что вы каскадируете обратный вызов этого события вниз по телу.

<CascadingValue Value=btn_clicked >
    @Body
</CascadingValue>

Теперь в вашем коде Index.razor установите свойство:

[CascadingParameter]
public EventCallback btn_clicked { get; set; }
person Neville Nazerane    schedule 27.09.2019

Спасибо. Первый ответ был именно тем, что мне было нужно, хотя мне нужно было передать параметр, поэтому он такой же, как указано, за исключением:

В MainLayout.razor:

public EventCallback<string> EventName => EventCallback.Factory.Create<string>(this, MethodName);

В Index.razor:

[CascadingParameter]
protected EventCallback<string> EventName { get; set; }

Чтобы вызвать метод:

EventName.InvokeAsync("Name");
person James Thomas    schedule 13.11.2019
comment
Это сработало, тогда как принятый ответ не сработал, когда я адаптировал его для приема параметра. - person Tod; 30.07.2020