【问题标题】:Can you send different view models to a view?您可以将不同的视图模型发送到视图吗?
【发布时间】:2011-06-21 02:41:18
【问题描述】:

假设我正在为 Food 实现一个视图。 (ASP.NET MVC2)

然后根据类型(例如水果或蔬菜),我将更改视图。

我可以在不为水果和蔬菜创建单独视图的情况下执行此操作吗?

即假设我们有像 http://localhost:xxxx/Food/{foodID}

这样的 url 结构

不想

http://localhost:xxxx/Veg/{foodID}

http://localhost:xxxx/Fruit/{foodID}

所以我希望能够根据类型更改视图。我正在使用 telerik 的 tabstrip 控件,让您了解视图的差异 - 只是说 - 不为 Veg 显示一个特定的选项卡,例如,如果是水果则显示它。

一个视图可以接受两个不同的视图模型吗?所以当我们点击http://localhost:xxxx/Food/{foodID} 时,代码确定对象是什么类型(水果或蔬菜),然后发送 FruitViewModel 或 VegetableViewModel ?如果我只发送一个视图模型,我如何控制在视图中显示或不显示某些内容的逻辑?

【问题讨论】:

    标签: c# asp.net asp.net-mvc-2 view viewmodel


    【解决方案1】:

    如果您将FoodViewModel 定义为基类并让FruitViewModelVegetableViewModel 扩展它,您可以拥有ViewPage<FoodViewModel> 并传入其中一个。然后,您的视图可以检查它获得的特定子类并呈现适当的输出。

    或者,如果FruitViewModelVegetableViewModel 之间的唯一区别是一个是水果,一个是蔬菜(但所有其他属性都是共享的,即Name, Calories, Color, Cost),则在共享上具有FoodType 属性FoodViewModel 并使用它来有条件地呈现适当的输出。

    【讨论】:

    • “然后,您的视图可以检查它获得的特定子类并呈现适当的输出。” - 你如何在视图中做到这一点??
    • etc.
    • 按照我阅读问题的方式,两个视图之间的唯一区别将类似于 tabStrip.Tab[i].Visible = isFruit;这就是为什么我认为复制其他 n 行 View 代码是不明智的。如果你的观点会因食物的种类而有更大的差异,那肯定有不同的观点。
    【解决方案2】:

    最佳选择取决于水果和蔬菜视图的差异程度:

    备选方案 1:

    您可以创建两个不同的视图(您可以将视图名称传递给 View 方法):

    public ViewResult Food(int id)
    {
        var food = ...
        if (/* determine if food is Veg or Fruit */)
            return View("Fruit", new FruitViewModel { ... });
        else
            return View("Veg", new VegViewModel { ... });
    }
    

    通过返回不同的视图,url 不会改变(就像使用 return RedirectToAction("Action", "Controller", ...) 时一样,这意味着 HTTP 重定向。

    备选方案 2:

    您可以通过FruitViewModelVegViewModel 扩展公共FoodViewModel。然后您的 FoodView 可以是 FoodViewModel 类型并决定在您的视图代码中显示什么。

    【讨论】:

    • 我以为他想对两者使用相同的视图,但只需在单个选项卡上设置启用或可见属性,其余视图在任何一种情况下都相同。
    • 最初我做得很好,但真正的目标只是将 url 结构保持在一起,而不是将其拆分为水果和蔬菜
    【解决方案3】:

    如果您唯一需要更改的是 tabstrip 设置。您可以在 ViewModel 上提供一个名为“ShowTabItem”的属性,然后将该属性绑定到视图中的 TabStripItem。

    public class FoodViewModel
    {
        Food _food;
    
        public FoodViewModel(Food food)
        {
    
        }
    
        public bool ShowTabItem
        {
            get
            {
                return _food.Type == FoodType.Vegetable;
            }
        }
    }
    

    将 ShowTabItem 属性绑定到 tabstrip 项的 Visibility 或 Enabled 属性。 (随便)

    那么你的控制器就是

    public ActionResult Food(int id)    
    {
        Food food = getFood(id);
        return View(new FoodViewModel(food));
    }
    

    让您的 ViewModel 决定需要显示的内容。

    希望这会有所帮助!

    【讨论】:

    • +1 这是最好的解决方案,除了我将把它的逻辑放在控制器中,只是让 ShowTabItem 成为一个简单的属性。这意味着您可以更改定义选项卡是否应显示在控制器中而不是视图模型中的逻辑,它应该只是视图所需数据的哑保持器
    猜你喜欢
    • 2023-02-14
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    • 2011-05-06
    • 2011-01-07
    • 1970-01-01
    • 2011-06-12
    • 2018-08-17
    相关资源
    最近更新 更多