如何根据对象类型选择视图


How to choose a view based on object type?

我有4个对象(Novel, Short Story, Non-Fiction,科幻),它们都是从Book基类扩展而来的。用户可以查看图书详细信息页面,该页面应该根据图书类型显示一组不同的详细信息。因此,理想情况下,我可以有4个不同的视图脚本,将根据所选书籍的类型调用。我该怎么做呢?我应该在每个对象中存储到视图脚本的链接吗?我应该在控制器动作中有一个开关语句来确定正确的视图吗?

将视图脚本/文件命名为带有details后缀的对象(例如novel_details.php)。

所以当你显示/呈现视图时,你解析带有细节后缀

的对象名称
$this->render( $object->name."_details.php");*

编辑:*这一切都取决于你使用的MVC框架。

您是自己实现MVC,还是使用预先存在的框架?rails类型的框架通常在类/方法和请求之间有一个很好的映射,例如:

GET /book/view/id/1 --> Book::view(1)

根据模型的结构,这可以映射到图书GUID;或者,如果您坚持使用这样的类型层次结构,您可能更喜欢这样:

GET /book/view/type/novel/id/3 --> Novel::view(3)

其中id指的是小说,而不是书。还:

GET /novel/view/id/3 --> Novel::view(3)

的作用相同。

也许更有针对性的是,你应该更喜欢组合而不是继承;有什么理由要有四种类型的书吗?它们到底有什么不同?如果它们只是在它们所包含的元数据类型上有所不同,您可能会考虑以某种方式封装这种差异,而不是向下移动类型层次结构(例如;如果影响各种图书类型的方法是相似的,您可以简单地提出适用于特定图书类型的任何算法,并使用对象组合在您的类中包含该功能)。我认为这也将允许你简化你的视图结构,从而间接地给你一个更清晰的解决方案来解决这个问题。

你可以…

$bookTypeToView = array(
   'novel' => 'novel.php',
   'short_story' => 'short.php'
   ...
);

然后做类似的事情…

$this->view = isset($bookTypeToView[$book['type']]) ? $bookTypeToView[$book['type']] : 'default';