【问题标题】:Blazor - Keeping user preferences in a tiled dashboard appBlazor - 在平铺仪表板应用程序中保留用户首选项
【发布时间】:2021-06-03 14:58:43
【问题描述】:

我有一个仪表板应用程序,它向用户显示某些应用程序,从数据库加载..

瓷砖是可拖动的(Jquery)。但我很难理解如何移动瓷砖,然后保持状态,以便用户第二天可以回来,仍然有他的偏好。

我曾尝试关注 Telerik 演示,但不幸的是,我是一名学生,我买不起许可证。有没有人做过类似的事情来保持用户的偏好?

这是 Telerik 演示,我正在为模型中的内容而苦苦挣扎。

状态的本地存储

using Microsoft.JSInterop;
using System.Text.Json;
using System.Threading.Tasks;

namespace TelerikBlazorDemos.Services
{
    public class LocalStorage
    {
        protected IJSRuntime JSRuntimeInstance { get; set; }

        public LocalStorage(IJSRuntime jsRuntime)
        {
            JSRuntimeInstance = jsRuntime;
        }

        public ValueTask SetItem(string key, object data)
        {
            return JSRuntimeInstance.InvokeVoidAsync(
                "localStorage.setItem",
                new object[] {
                    key,
                    JsonSerializer.Serialize(data)
                });
        }

        public async Task<T> GetItem<T>(string key)
        {
            var data = await JSRuntimeInstance.InvokeAsync<string>("localStorage.getItem", key);
            if (!string.IsNullOrEmpty(data))
            {
                return JsonSerializer.Deserialize<T>(data);
            }

            return default;
        }

        public ValueTask RemoveItem(string key)
        {
            return JSRuntimeInstance.InvokeVoidAsync("localStorage.removeItem", key);
        }
    }
}

这是我正在努力解决的部分.. @Code{ }

@page "/tilelayout/persist-state"

@inject LocalStorage LocalStorage
@inject IJSRuntime JsInterop

@using TelerikBlazorDemos.Shared.DemoConfigurator
<DemoConfigurator>
    <DemoConfiguratorColumn>
        <TelerikButton OnClick="@SaveState" Icon="save" Class="mr-xs">Save State</TelerikButton>
        <TelerikButton OnClick="@ReloadPage" Icon="reload" Class="mr-xs">Reload the page</TelerikButton>
        <TelerikButton OnClick="@LoadState" Icon="download" Class="mr-xs">Load last State</TelerikButton>
        <TelerikButton OnClick="@SetExplicitState" Icon="gear" Class="mr-xs">Configure State</TelerikButton>
    </DemoConfiguratorColumn>
</DemoConfigurator>

<div class="demo-alert demo-alert-info" role="alert">
    <strong>Change the Tile Layout</strong> (resize and reorder some tiles, remember their order) and
    <strong>Save</strong> the TileLayout state, then <strong>Reload</strong> the page to see the state persisted.
    <strong>Change</strong> the layout some more and <strong>Load</strong> the state to see the last one preserved.
    You can manage the TileLayout state with your own code to put it in a specific configuration through the <strong>Configure</strong> button.
    This demo will remember your last layout until your clear your browser storage or click the Configure button to put it in its initial state.
</div>

<div style="display: inline-block;">
    <TelerikTileLayout @ref="@TileLayoutInstance"
                       Columns="3"
                       ColumnWidth="285px"
                       RowHeight="285px"
                       Resizable="true"
                       Reorderable="true">
        <TileLayoutItems>
            <TileLayoutItem HeaderText="San Francisco">
                <Content>
                    <img class="k-card-image" draggable="false" src="images/cards/sanfran.jpg" />
                </Content>
            </TileLayoutItem>
            <TileLayoutItem HeaderText="South Africa">
                <Content>
                    <img class="k-card-image" draggable="false" src="images/cards/south-africa.jpg" />
                </Content>
            </TileLayoutItem>
            <TileLayoutItem HeaderText="Sofia" RowSpan="2">
                <Content>
                    <img class="k-card-image" draggable="false" src="images/cards/sofia.jpg" />
                    <div class="text-center">
                        <div class="k-card-body">
                            <p>Sofia is the largest city and capital of Bulgaria. Sofia City Province has an area of 1344 km<sup>2</sup> while the surrounding and much bigger Sofia Province is 7,059 km<sup>2</sup>. The city is situated in the western part of the country at the northern foot of the Vitosha mountain, in the Sofia Valley that is surrounded by the Balkan mountains to the north. The valley has an average altitude of 550 metres (1,800 ft). Unlike most European capitals, Sofia does not straddle any large river, but is surrounded by comparatively high mountains on all sides.</p>
                            <br />
                            <em>* The data used in this demo is taken from <a href="https://wikipedia.com" target="_blank"><em>wikipedia.com</em></a></em>
                        </div>
                    </div>
                </Content>
            </TileLayoutItem>
            <TileLayoutItem HeaderText="Rome" ColSpan="2" RowSpan="2">
                <Content>
                    <img class="k-card-image image-center" draggable="false" src="images/cards/rome.jpg" />
                    <div class="text-center">
                        <div class="k-card-body">
                            <p>
                               
                            </p>
                            <p>
                                <em>* The data used in this demo is taken from <a href="https://wikipedia.com" target="_blank"><em>wikipedia.com</em></a></em>
                            </p>
                        </div>
                    </div>
                </Content>
            </TileLayoutItem>
            <TileLayoutItem HeaderText="Barcelona">
                <Content>
                    <img class="k-card-image" draggable="false" src="images/cards/barcelona.jpg" />
                </Content>
            </TileLayoutItem>
        </TileLayoutItems>
    </TelerikTileLayout>
</div>

@code { TelerikTileLayout TileLayoutInstance { get; set; }
            TileLayoutState SavedState { get; set; }
            string stateStorageKey = "TelerikBlazorTileLayoutStateDemoKey";

            async Task SaveState()
            {
                var state = TileLayoutInstance.GetState();
                await LocalStorage.SetItem(stateStorageKey, state);
            }

            async Task LoadState()
            {
                TileLayoutState storedState = await LocalStorage.GetItem<TileLayoutState>(stateStorageKey);
                if (storedState != null)
                {
                    TileLayoutInstance.SetState(storedState);
                }
            }

            void ReloadPage()
            {
                JsInterop.InvokeVoidAsync("window.location.reload");
            }

            async void SetExplicitState()
            {
                TileLayoutState desiredState = GetDefaultDemoState();
                TileLayoutInstance.SetState(desiredState);
                await SaveState();
            }

            protected override async Task OnAfterRenderAsync(bool firstRender)
            {
                var state = await LocalStorage.GetItem<TileLayoutState>(stateStorageKey);
                if (state != null && TileLayoutInstance != null)
                {
                    TileLayoutInstance.SetState(state);
                }
            }

            TileLayoutState GetDefaultDemoState()
            {
                TileLayoutState defaultDemoState = new TileLayoutState()
                {
                    ItemStates = new List<TileLayoutItemState>()
            {
                new TileLayoutItemState { Order = 1, ColSpan = 1, RowSpan = 1 },
                new TileLayoutItemState { Order = 2, ColSpan = 1, RowSpan = 1 },
                new TileLayoutItemState { Order = 3, ColSpan = 1, RowSpan = 2 },
                new TileLayoutItemState { Order = 4, ColSpan = 2, RowSpan = 2 },
                new TileLayoutItemState { Order = 5, ColSpan = 1, RowSpan = 1 },
            }
                };
                return defaultDemoState;
            } }

<style>
    .k-card-image {
        width: 285px;
        height: 189px;
    }

    .k-card-body {
        overflow: auto;
    }

    .image-center {
        display: block;
        margin: auto;
    }
</style>

例如 TileLayoutInstance.SetState(storedState);我不知道这是如何在发动机罩后面设置的。 p.s 我正在使用 .netCore5 和 Visual Studio 2019。非常感谢任何帮助。

【问题讨论】:

    标签: html asp.net-core blazor


    【解决方案1】:

    为了保存用户的状态,我建议将图标的顺序和 ID 存储在数据库中。 (我对 Blazor 本地存储没有太多经验)然后我将为每个用户创建一个 C# 仪表板对象,其中包含他们所需图标的有序列表。我还将为每个图标创建一个 C# 对象,其中包含呈现 TileLayoutItem 所需的信息。

    在第一次使用时,我会让用户设置他们的仪表板并调用保存方法,以便您可以按照需要呈现的顺序创建图标列表。如果您设置了身份验证,则将此列表保存到与用户帐户对应的数据库中,或者为每个用户创建一个特定的用户 ID。

    您可以将这些存储在您熟悉的任何数据库中,也可以按照 Entity Framework Core EF For Blazor Server 的方式进行设置。

    当用户请求页面进行查询以拉取特定用户的图标时,如果尚未将此列表排序为用户的偏好,然后使用组件中的 @foreach() 语句根据存储的信息呈现 TileLayoutItem在每个图标对象中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-29
      • 2015-01-27
      • 2011-05-29
      • 2014-05-06
      • 1970-01-01
      • 2016-09-10
      • 2011-03-08
      • 2023-02-10
      相关资源
      最近更新 更多