我在网上看到很多关于 MVC 架构的不同图片的资源。其中一些显示 View 组件将呈现传递给 Controller,然后 Controller 向用户提供响应;像这样:第一张图 查看视图如何获取演示文稿以及控制器如何发送响应

其他的展示了View组件直接将结果呈现给用户而不需要和controller进行交互;像这样:第二张图 在这里查看视图如何将响应直接发送给用户,而控制器仅与模型交互并将数据传递给视图

这让我很困惑,尤其是在看到 2 篇关于 GFG 的文章之后,每一篇对 MVC 的解释都不一样。那么哪个是正确的呢?如果第一种情况是正确的,那么谁负责渲染?

PS:我正在做一个laravel项目,需要了解这些信息。


更新

这篇关于 Model View Controller 的文章中,它部分说:

除了将应用程序划分为这些组件之外,模型-视图-控制器设计还定义了它们之间的交互。

  • 该模型负责管理应用程序的数据。它从控制器接收用户输入。

  • 视图以特定格式呈现模型的表示。

  • 控制器响应用户输入并对数据模型对象执行交互。控制器接收输入,可选择对其进行验证,然后将输入传递给模型。

没有提到哪种类型的对象将演示文稿发送给用户

实际上,这两个图在技术上都是可行的,但不幸的是,第二个图缺乏足够的描述,因此误导性可能较小。数据,通常以模型对象的形式,由控制器发送到视图(还有另一种可能性,将进行描述),然后视图使用该数据创建将发送给用户的演示文稿。然后,View 通常将数据发送给用户,但它也可以将数据返回给执行实际发送的 Controller。只有在这个意义上,View 和 Controller 之间的通信才是双向的。但最终是 View 负责创建演示文稿。

让我详细说明:

控制器

  1. 响应“参与者”生成的事件。我所说的参与者是指在所讨论的应用程序之外与该应用程序交互的任何事物(例如,一个人、另一个应用程序等)。因此,一个典型的例子是响应“用户”生成的事件,例如鼠标单击、表单提交、应用程序请求。所以控制器对象显然处理输入。
  2. 控制器使用输入事件来实现“用例”,它表示应用程序实现某些有形目标的特定用法(场景)。因此,它调用潜在的多个模型对象,这些模型对象可能彼此一无所知,因此“在更高级别”执行业务逻辑。
  3. 最后,控制器对象通常会通过调用模型对象产生某种结果。有时,控制器然后将数据传递给视图,而视图本身可能会将该数据的呈现发送给用户或将其返回给控制器以呈现给用户。也有可能一个或多个视图对象已将自己注册为某个模型对象更改的“观察者”。然后,当控制器修改了模型时,视图会收到通知并通过向模型询问其数据进行响应,然后使用该数据更新其表示,而无需控制器的任何参与。

模型

模型对象通常表示问题域中的某个实体,例如客户、帐户等,或者从执行用例中生成的结果。它对封装为其状态的数据执行创建、读取、更新和删除 (CRUD) 操作(数据逻辑),并公开对其状态进行操作的方法(业务逻辑)。

看法

我在讨论Controller时已经对View说了很多,所以请原谅这里的重复。

A result obtained by the controller generally needs to be "viewed" by an actor. Sometimes the controller passes dats to the controller, quite often as a model object, and the view then presents it in some format to the "user" (actor). For example, in a web application a view object might transform the model object into HTML and then send the HTML to the actor's browser or return the HTML back to the controller, which does the actual sending of the HTML to the browser. Or there could be multiple views on a single model object that are sent to the user, which occurs frequently in GUI-based application. In this case the view objects register themselves as "observers" of a model object and are notified whenever the model object has been updated. The view objects then retrieve the updated model data and use it to update the presentation with no interaction from the controller.


正常情况下应该是controller,但是简单的想一下语句return被调用的对象和位置。那就是将响应传回给请求者的那个,但是实际的响应结构是由 laravel 路由器处理的,它是构建实际响应标头和正文的那个

这是一个您可以与您的想法争论并通过响应的示例

// we could say response is process by closure/anonymous function
Route::get('/test-1', function () {
    return 'Response 1';
});

// we could say the response is process by response helper function
Route::get('/test-2', function () {
    return response(['test' => 1, 'test2' => 2 ] )
        ->header('header1', 'value 1')
        ->header('header2', 'value 2');
});

// we could say the response is process by response helper function but also calls the view method for the actual response body and status code
Route::get('/test-3', function () {
    return response()
        ->view('test', $something, 200)
        ->header('header-1', 'value1');
});

但通常在 Laravel 中,你应该将路由传递给处理数据的控制器,然后生成一个返回语句,你可以说控制器是做出响应的那个,如果你想返回一个 html 主体,那么你应该调用view方法构造html结构。

IE

Route::get('/test-4/{id}', [YourController::class, 'method1']);
Route::get('/test-5/{id}', [YourController::class, 'method2']);

然后你的控制器

class YourController extends Controller {


    // return with view
    public function method1($id) {

        $data = YourModel::find($id);

        return view('model-view', compact('data') );
    }

    // leave laravel router to transform your data into a json format when returning to the user
    public function method2($id) {

        $data = YourModel::find($id);

        return $data;
    }


    // format your own json as the response
    public function method3($id) {

        $data = YourModel::find($id);

        return response()->json(['data' => $data ], 200);
    }
}

在这里抢劫

这样假设是安全的

谁将响应传回给用户?- 它始终是处理一切的路由器,无论是字符串、json、html、文件、异常等。它是处理响应标头和正文的路由器

谁作出回应?- 拥有返回/渲染语句的人或抛出错误的人。

视图是否将响应直接传回给用户?- 总是不,一切都传回处理响应的路由器。视图只是动态 html 格式的包装器。随着前端框架的兴起,即使laravel内部支持react和vue,视图也永远不会被使用,除非你使用blade模板


只需与用户的每次交互都在控制器中。

当您收到请求时,请调用控制器功能。

当您想返回生成的响应时,可以是视图或 JSON,也可以是您在控制器中执行的任何操作!

所以你的答案是控制器。你在两个图中都看到了。

在第一个控制器中获取视图并发送。

在第二个控制器中,控制器向用户发送视图并与用户交互。


在模型-视图-控制器 (MVC) 体系结构中,控制器负责接收用户输入并确定适当的响应以发送回用户。控制器负责处理和解释输入,根据输入和应用程序的逻辑做出决策,然后相应地更新模型。

模型更新后,控制器会将更新后的数据传递给视图,视图负责向用户呈现响应。视图从控制器接收数据,对其进行适当的格式化,然后以视觉上吸引人且易于理解的方式将其呈现给用户。

因此,虽然控制器和视图在 MVC 架构中都扮演着重要的角色,但最终还是控制器将响应传递给了用户。


它始终是控制器,而且只能是控制器。这是MVC的一个基本原则。您应该始终遵守规则并仅通过控制器发送响应对象。


一些你的知识

在 Laravel 中,我们不需要Controlleralso。因为他们引入了一种叫做Route Model Binding 的机制,你可以在没有控制器支持的情况下返回数据。

例子

use App\Models\User;
 
Route::get('/users/{user}', function (User $user) {
    return $user->email;
});

除了我发现的以外,这对解释正确MVC 的Laravel 生命周期挂钩更加准确和详细

在此处输入图像描述

因此,在处理 API(Laravel 作为 API、Vue、React、Angular)时,我们将不再看到View


  1. Laravel 请求生命周期

我想它可以用两种不同的方式编码,或者甚至可以用两种不同的方式在概念上说明相同的基本代码架构。视图代码始终负责生成用户在屏幕上看到的用户界面组件。控制器将数据传递给视图并告诉它执行和呈现 UI(这将是 Web 应用程序中的 HTML 文档)。然后,控制器可能会获取该 HTML 并将其返回到它返回给浏览器的 HTTP 响应中(尽管从技术上讲,它可能会将其返回到网络服务器,然后再将其传递给浏览器)。

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部