首页 > 解决方案 > 异步更新属性

问题描述

当我的 ViewModel 的一个属性被更新时,其他属性被异步更新。

待办事项.cshtml:

@page "/todo"

<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>

<ul>
    @foreach (var todo in todos)
    {
        <li>
            <input type="checkbox" bind="@todo.IsDone" />
            <input bind="@todo.Title" />
        </li>
    }
</ul>

<input placeholder="Something todo" bind="@newTodo"/>
<button onclick="@AddTodo">Add todo</button>

@functions {
    IList<TodoItem> todos = new List<TodoItem>();


    string newTodo;
    void AddTodo()
    {
        if (!string.IsNullOrWhiteSpace(newTodo))
        {
            todos.Add(new TodoItem { Title = newTodo });
            newTodo = string.Empty;
        }
    }
}

TodoItem.cs:

public class TodoItem
{
    private bool _isDone;

    public string Title { get; set; }
    public bool IsDone
    {
        get => _isDone;
        set
        {
            _isDone = value;
            Task.Run(() =>
            {
                //Simulate work
                System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));
                //Update property
                Title = Title + " - Done";
            });
        }
    }
}

在同步(没有 Task.Run)中,这项工作正常,但在异步中,UI 不会更新。

我需要解释要更新的 UI StateHasChanged()https ://github.com/aspnet/Blazor/issues/1413

但是我不能在 TodoItem 中调用这个方法(而且我不希望 TodoItem 知道 Blazor 组件)。

您有更新 UI 的解决方案吗?

标签: c#.netblazor

解决方案


您应该执行以下操作:

  1. 在你的类中定义一个动作委托:

     public event Action OnChange;
    
  2. 在这个类中定义一个方法NotifyStateChanged()如下:

     private void NotifyStateChanged() => OnChange?.Invoke();
    

    此方法触发OnChange事件。在完成它所做的任何任务后,您应该从您的逻辑中调用此方法。

  3. 在你的 todo 组件中,将StateHasChanged方法添加到你的类中使用的事件委托中TodoItem

     @functions
     {
         protected override void OnInit()
         {
             state.OnChange += StateHasChanged;
         }
     }
    

推荐阅读