【问题标题】:Is a ViewModel really necessary if there's going to be only one property in it? [closed]如果 ViewModel 中只有一个属性,真的有必要吗? [关闭]
【发布时间】:2021-06-16 16:44:54
【问题描述】:

我的 MVC (.NET 5) 应用程序中有一个名为“资产/索引”的视图,我在其中显示资产表中的资产列表。该页面以IList<Asset> 为模型,即@model IList<Asset>。我的同行建议我为该视图制作一个 ViewModel,但在这种情况下真的需要 ViewModel 吗?我的意思是我看到的唯一优势是,向页面添加另一个属性(如果将来需要)很容易,因为在这种情况下我肯定需要一个 ViewModel。但是,由于该页面的唯一目的是显示资产列表(而且我很确定将来不需要向该假设的 ViewModel 添加属性),我很困惑是否遵循我的直觉或同行的建议。


观点:

@using AdminPortal.Models;
@model IReadOnlyList<Asset>
@{ 
    ViewData["Title"] = "List";

}

@{ await Html.RenderPartialAsync("../Partials/SearchPartial", "AssetsController"); }

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

<script type="text/javascript">
    document.getElementById('list-btn').hidden = true;
</script>

<p>
    <a asp-action="Create" class="btn-link">Create New</a>
</p>

<table class="table">
    <thead class="thead-light">
        <tr>
            <th>@Html.DisplayNameFor(model => model.First().Id)</th>
            <th>@Html.DisplayNameFor(model => model.First().Address)</th>
            <th>@Html.DisplayNameFor(model => model.First().State)</th>
            <th>@Html.DisplayNameFor(model => model.First().Temperature)</th>
            <th>@Html.DisplayNameFor(model => model.First().Moisture)</th>
            <th>@Html.DisplayNameFor(model => model.First().Alerts)</th>
            <th>@Html.DisplayNameFor(model => model.First().LastServiced)</th>
            <th>Actions</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var asset in Model)
        {
            <tr>
                @if (asset.State != AssetState.deleted)
                {
                    <td>
                        <a asp-action="Index" asp-controller="Home"
                           asp-route-id="@asset.Id">@Html.DisplayFor(item => asset.Id)</a>
                    </td>
                }
                else
                {
                    <td>
                        <a>@Html.DisplayFor(item => asset.Id)</a>
                    </td>
                }
                <td>@Html.DisplayFor(item => asset.Address)</td>
                <td>
                    @if (asset.State != AssetState.deleted)
                    {
                        var IdName = "assetStateDropdown" + asset.Id;
                        <select class="dropdown" id="@IdName">
                            <option class="dropdown-item dropdown-item-text"
                                    value="@AssetState.functional">
                                functional
                            </option>
                            <option class="dropdown-item dropdown-item-text"
                                    value="@AssetState.non_functional">
                                non-functional
                            </option>
                            <option class="dropdown-item dropdown-item-text"
                                    value="@AssetState.under_maintenance">
                                under-maintenance
                            </option>
                        </select>
                        <script type="text/javascript">
                            //change the state of the asset from the dropdown
                            $(function () {
                                $("#@IdName").change(function () {
                                    $.ajax({
                                        type: "POST",
                                        url: "/Assets/UpdateState",
                                        data: {
                                            "state": $("#@IdName").val(),
                                            "id": '@asset.Id'
                                        },
                                        success: function (response) {
                                            alert("State Changed");
                                        },
                                        failure: function (response) {
                                            alert("Could not Change state");
                                        },
                                        error: function (response) {
                                            alert("Some error occurred. Try again later");
                                        }
                                    });
                                });
                            });
                        </script>
                        <script type="text/javascript">
                            //set the value of the asset state drop down to the current state
                            document.getElementById('@IdName').value = '@asset.State';
                        </script>
                    }
                    else
                    {
                        <p>deleted</p>
                    }
                </td>
                <td>@Html.DisplayFor(item => asset.Temperature)</td>
                <td>@Html.DisplayFor(item => asset.Moisture)</td>
                <td>
                    <a asp-action="Index" asp-controller="Alerts"
                       asp-route-id="@asset.Id">@Html.DisplayFor(item => asset.Alerts.Count)</a>
                </td>
                <td>@Html.DisplayFor(item => asset.LastServiced)</td>
                @if (asset.State != AssetState.deleted)
                {
                    <td>
                        <a asp-action="Delete" asp-route-id="@asset.Id" class="btn-link" style="color: darkred">Decommission</a>
                    </td>
                }
            </tr>
        }
    </tbody>
</table>

建议的 ViewModel:

public class IndexViewModel
{
    public IReadOnlyList<Asset> Assets { get; set; }
}

【问题讨论】:

  • 恕我直言,这是一个自以为是的问题,唯一的意见是您和您的团队的意见。只有您/您的团队知道您现在和未来的数据使用/需求/设计范围。话虽如此,您的同行有“正确”的意见(期货、可重用性等)
  • 有必要吗?在您的情况下,只有这样,没有。但是:它吗?也没有。这个问题是否离题,因为它纯粹是基于意见的?肯定是的。
  • @EdSF,好的,但请告诉我,为什么标题为“列出资产”的视图(在上面的代码中省略)会用于任何其他原因?这样做似乎很自然。少一门课要照顾...

标签: c# .net-5 asp.net-mvc-viewmodel


【解决方案1】:

简洁是为了简单和更少的文件,而冗长是为了更容易扩展。

我见过有大量不必要的 ViewModel 的项目,这些 ViewModel 会造成空间混乱,但也有一些项目由于缺少 ViewModel 而增加了额外的布尔标志或标题元素变得更加困难。

案例可以采用任何一种方式,最终取决于您的团队决定的偏好或编码风格,并与项目其余部分的一致性相匹配。如果人们期望模型在某个地方,那么当他们不在的时候可能会很不协调,但如果 ViewModel 在该代码库中是可选的,那么它会更容易接受。

您永远不知道未来的需求,可能需要一些相关的用户信息、功能或扩展。即使没有可扩展性,如果代码库的其余部分都为每个页面都设置了视图模型,那么阅读代码库的开发人员将会期望这种布局,因此对于您的一个页面来说,省略 ViewModel 因为它非常简单实际上可能会结束由于不一致而导致可读性降低。

【讨论】:

  • 就像你说的那样,ViewModel 确实为未来的变化提供了便利,但我真的不明白为什么显示资产列表的视图需要假设的 ViewModel 中的任何其他属性。 :)
  • 能否请您在答案中添加this 评论,以便我接受?
猜你喜欢
  • 1970-01-01
  • 2019-10-29
  • 2014-10-08
  • 2018-04-05
  • 2021-01-25
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
  • 1970-01-01
相关资源
最近更新 更多