# 文章评论
博客已经部署,我们写了一些非常好的博客帖子,并通过Adminer发布。 人们正在阅读博客,他们非常热衷于我们的想法。 我们每天都收到很多赞美的电子邮件。 但是,当我们只有在电子邮件中,所以没有其他人可以阅读它的所有赞美? 如果人们可以直接在博客上评论,以便其他人可以阅读我们是多么真棒,这不会更好吗?
# 创建新表
我们用工具创建一个新表格InnoDB类,名称为comments
![](https://box.kancloud.cn/f6e6c29ebe4b7a08f72c4aee616dba4b_705x289.png)
~~~
CREATE TABLE `comments` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`post_id` int(11) NOT NULL,
`name` varchar(250) NOT NULL,
`email` varchar(250) NOT NULL,
`content` text NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`)
) ENGINE=InnoDB CHARSET=utf8;
~~~
如果创建时出错,查看是否第一个posts表是不是InnoDB类型。
# 表单
首先,我们需要创建一个表单,这将允许用户对我们的页面发表评论。 Nette Framework对表单提供了极好的支持。 它们可以在控制器中配置并在模板中呈现。
Nette Framework有一个组件的概念。 组件是可重用的类或代码片段,可以附加到另一个组件。 即使控制器是一个组件。 每个组件都是使用组件中心创建的。 所以让我们在PostPresenter中加入以下代码。
~~~
protected function createComponentCommentForm()
{
$form = new Form; // means Nette\Application\UI\Form
$form->addText('name', 'Your name:')
->setRequired();
$form->addEmail('email', 'Email:');
$form->addTextArea('content', 'Comment:')
->setRequired();
$form->addSubmit('send', 'Publish comment');
return $form;
}
~~~
让我们解释一下。 第一行创建一个Form组件的新实例。
以下方法将HTML输入附加到表单定义中。 - > addText将呈现为<input type = text name = name>,带有<label>您的姓名:</ label>。 正如你可能已经猜到了, - > addTextArea附加一个<textarea>和 - > addSubmit添加一个<input type = submit>。 有更多的方法,但这是所有你必须知道,现在。 您可以在文档中了解更多。
一旦在控制器中定义了表单组件,我们可以在模板中显示它。因此,请将{control}放在帖子详细信息模板的末尾,在app / presenters / templates / Post / show.latte中。 因为组件的名称是commentForm(它是从方法createComponentCommentForm的名称派生的),
~~~
...
<h2>Post new comment</h2>
{control commentForm}
...
~~~
意思是你在show.latte里面加入以上代码就象以下一样
![](https://box.kancloud.cn/d874390e5f56ff5ee52b1ad6c3dca663_526x305.png)
再刷新文章详细页面,就了现了表单!
![](https://box.kancloud.cn/9a75d043799ea6073f884cc0fea9b5c5_433x435.png)
# 批论保存到数据库
现在可以尝试提交一些数据? 您可能已经注意到,表单没有执行任何操作。 它只是在那里,看起来很酷,什么也不做。 我们必须给它附加一个回调方法,这将保存提交的数据。
将以下行放在组件工厂中返回行之前的createComponentCommentForm中:
~~~
$form->onSuccess[] = [$this, 'commentFormSucceeded'];
~~~
![](https://box.kancloud.cn/f693ee261db83604978db9e3d687cd92_533x325.png)
这意味着“表单成功提交后,调用当前控制器的方法commentFormSucceeded”。 但是这个方法还不存在,所以让我们来创建它。
~~~
public function commentFormSucceeded($form, $values)
{
$postId = $this->getParameter('postId');
$this->database->table('comments')->insert([
'post_id' => $postId,
'name' => $values->name,
'email' => $values->email,
'content' => $values->content,
]);
$this->flashMessage('Thank you for your comment', 'success');
$this->redirect('this');
}
~~~
以上代码一定要放在createComponentCommentForm()下面
![](https://box.kancloud.cn/8a08cf712e1a184b40218913009c72a6_658x531.png)
新方法有一个参数,它是被提交的表单的实例,由createComponentCommentForm()创建。 我们收到在$values中提交的值。 然后我们将数据插入数据库。
当我们提交时 $this->flashMessage('Thank you for your comment', 'success');
会产生信息提示,但是他都是在上部出现,如果我们想把这个信息提交按模板
出现,那我们应如下操作,先在
app/presenters/templates/@layout.latte
中加入以下代码
~~~
<div n:foreach="$flashes as $flash" n:class="flash, $flash->type">{$flash->message}</div>
~~~
![](https://box.kancloud.cn/0b88c9d41948e4cb8a8f16ab3256c781_782x207.png)
我们再试一次就明白了。
# 显示评论
Nette \ Database有一个很酷的功能,名为Selection API。 你还记得我们创建的表是InnoDB吗? 管理员创建了所谓的外键,这将为我们节省大量的工作。
Nette \ Database使用外键来解析表之间的关系,并且知道关系,它可以自动为您创建查询。
你还记得,我们已经将$ post变量传递给PostPresenter :: renderShow()中的模板,现在我们要遍历所有的post_id等于$ post-> id的评论。 你可以通过调用$ post-> related('comments')。 就是这么简单。 看看结果代码。
~~~
public function renderShow($postId)
{
...
$this->template->post = $post;
$this->template->comments = $post->related('comments')->order('created_at');
}
~~~
![](https://box.kancloud.cn/cd7e0da5f02fa79e9fb639bb802ddc7d_697x268.png)
然后在show.latte模板中加入以下代码
![](https://box.kancloud.cn/68f13e0d3f57a9bbc12f43cb965bf696_910x450.png)!
注意特殊的n:tag-if属性。 你已经知道n:属性如何工作。 嗯,如果你用tag-添加属性,它将只包裹标签,而不是它们的内容。 如果他们提供了电子邮件,这允许您将评论者的名字变成链接。 这两行结果相同:
![](https://box.kancloud.cn/7b137ca9bf176afe40b8330451eaea42_623x56.png)
- Nette简介
- 快速开始
- 入门
- 主页
- 显示文章详细页
- 文章评论
- 创建和编辑帖子
- 权限验证
- 程序员指南
- MVC应用程序和控制器
- URL路由
- Tracy - PHP调试器
- 调试器扩展
- 增强PHP语言
- HTTP请求和响应
- 数据库
- 数据库:ActiveRow
- 数据库和表
- Sessions
- 用户授权和权限
- 配置
- 依赖注入
- 获取依赖关系
- DI容器扩展
- 组件
- 字符串处理
- 数组处理
- HTML元素
- 使用URL
- 表单
- 验证器
- 模板
- AJAX & Snippets
- 发送电子邮件
- 图像操作
- 缓存
- 本土化
- Nette Tester - 单元测试
- 与Travis CI的持续集成
- 分页
- 自动加载
- 文件搜索:Finder
- 原子操作