上一篇文章我们简单地实现了Yii2框架安装和Hello World,而在这一篇文章当中,我们会带着好奇之心去探索一下在Yii2中的几个重要的元素组成:MVCFormsLayouts

本文的目标是创建一个小小的表单应用,就是实现一个简单的类似发微博的功能,但是我还不想牵扯到数据库那一块,因为其实数据库和表在Yii2框架之中其实还是有很多东西可以讲的,打算在下一篇的文章中会详细讲到。

MVC

模型(Model)对于我个人的简单理解就是一个概念集合,在这个集合里面包含该概念集合的多种数据,比如一个User会有姓名,性别等多个属性,这个概念集合通常就是对于数据库的一张表(如果还没有对应的数据表,则可以看作是一个集合的属性);而每一个具体的实例概念就对应一条数据记录。比如在这一篇文章之中我们会创建一个Status模型,代表状态(来源于生活:发一条状态),这个Status会有两个重要的属性,textpermissionstext就是状态本身,permissions是状态的权限。

视图(Views)通过控制器想模型请求数据,并将数据以某种特定的版式展示给用户。

控制器(Controller)可以向ModelViews发送不同的指令,一般是向Model取数据,然后读取视图文件来渲染输出数据。

在Yii2的应用中,一般是这样的:某个URL指向某个控制器的特定action,然后控制器负责向特定的模型取数据,然后将数据分配给视图渲染输出。

在这里说一下我个人的观点,我觉得其实在MVC当中,可能应该做事最多的应该是Model,与之相迎合的是,ControllerViews则相对要轻一些,Controller负责协调ModelViews,Views负责展示数据。

在Yii2的项目当中,我们将models文件放在/models/目录之下,所以我们在这个文件夹之下创建Status.php

<?php

namespace app\models;

use yii\base\Model;

class Status extends Model
{
const PERMISSIONS_PRIVATE = 10;
const PERMISSIONS_PUBLIC = 20; public $text;
public $permissions; public function rules()
{
return [
[['text','permissions'], 'required'],
];
} public function getPermissions() {
return array (self::PERMISSIONS_PRIVATE=>'Private',self::PERMISSIONS_PUBLIC=>'Public');
} public function getPermissionsLabel($permissions) {
if ($permissions==self::PERMISSIONS_PUBLIC) {
return 'Public';
} else {
return 'Private';
}
}
}

这里需要注意的是rules()这个方法,它会触发Yii自带的表单验证规则,比如这里就是textpermissions这两个表单输入框都不能为空,至于getPermissions()这个方法是为了在使用dropdown输入框的时候使用的。

Status模型创建好之后,我们就可以接着创建对应的控制器和方法。在平时的开发中我习惯是为每一个模型都创建一个对应的控制器,里面一般都是包含几个最常见的方法:indexcreatestoreupdatedelete等。这里我创建一个StatusController.php,这个文件应该是位于/controllers/文件夹当中,而我们希望实现一个发表状态的功能,我们必须需要一个create操作方法,比如我们的目的是:在用户访问http://localhost:8999/status/create的时候,我们可以展示创建一条状态的页面给用户。

<?php

namespace app\controllers;

use Yii;
use yii\web\Controller;
use app\models\Status; class StatusController extends Controller
{
public function actionCreate()
{
$model = new Status; if ($model->load(Yii::$app->request->post()) && $model->validate()) {
// $model 有post数据时直接展示
return $this->render('view', ['model' => $model]);
} else {
// 没有数据的时候,直接渲染create视图
return $this->render('create', ['model' => $model]);
}
}
}

首先,根据URL的规则,我们创建了一个actionCreate()方法,在这个方法里,我们通过条件判断来确定展示某个特定的视图。

创建好控制器和方法之后,我们就可以走到下一步了:创建视图。在Yii2中,视图文件的存放位置跟控制器的名字是息息相关的,比如上面我们创建了一个StatusController,我们现在首先需要在views/创建一个status/文件夹,然后在这个文件夹里创建各个跟StatusController相关的视图文件,比如上面actionCreate()return $this->render()两个视图:view.phpcreate.php

Forms

首先,我们需要一个Create视图来展示我们创建Status的表单(create.php):

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use app\models\Status;
?>
<?php $form = ActiveForm::begin();?>
<?= $form->field($model, 'text')->textArea(['rows' => '4'])->label('Status Update'); ?> <?=
$form->field($model, 'permissions')->dropDownList($model->getPermissions(),
['prompt'=>'- Choose Your Permissions -']) ?> <div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
</div> <?php ActiveForm::end(); ?>

在我们平时开发web应用的时候,表单几乎总是每时每刻都得存在,只要是需要收集信息的地方就需要表单。而Yii2在对表单支持这方面做得非常不错,就如你看到的一样,上面的Yii2 ActiveForm就是Yii2内置的用来帮助我们生成表单的小组件,这里需要注意的是dropDownList这个输入框式怎么实现的,它直接使用了getPermissions(),这个方法正好返回了一个我们需要的数组。

这时候访问:http://localhost:8999/status/create 就可以看到上面创建的表单了:

至于为什么就自动排版好了,不用我们写css,那是因为Yii2默认会给我们加载Bootstrap的css文件,所以我们在使用的时候直接指定类名就OK了。而且很明显地,我们可以看到,一旦输入框在失去焦点的时候,如果里面没有输入任何内容,每个输入框就会有相应的错误提示,用户体验很不错。这个其实是得益于我们在Status模型中声明的rules()方法,Yii2会根据指定的规则通过js在前端给出相应的验证。

然后我们尝试填入一些内容,你就会看到输入框的变化了:

点击Submit 按钮,表单会提交到StatusControlleractionCreate()方法,一旦有post数据传过来,就会渲染view.php视图:

到这里,其实我们就走通整个MVC的过程,并且在这个过程中,我们顺带说了一下Forms的知识点。

Layouts

为什么要说Layouts呢?因为Layouts在Yii中其实可以看作是视图中经常重复用到的部分,比如一个HTML文件的headernavigation bar 和footer等,这些都是几乎是在每一个视图文件中都会用到,所以Yii采取了一种一劳永逸的方法来管理这些共用的部分:Layouts就应运而生。这样你就不用在每一个view文件中重复不必要的代码了,而且又特别好管理。

Yii允许你创建多个Layouts,不过我貌似还没遇到那样的使用场景,所以还是无法给出有实证的说法,不管怎么说,一个Layouts就基本够用了。

最后,我们借着Layouts的东风来看看我们怎么修改一下Yii2的默认导航栏:添加一个新的导航。

在上一节我就提到过views\layouts\main.php这个文件,里面的具体结构你可以直打开来看看,我们这里改动的是Nav::widget这部分:

  echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right'],
'items' => [
['label' => 'Home', 'url' => ['/site/index']],
[
'label' => 'Status',
'items' => [
['label' => 'Create', 'url' => ['/status/create']],
],
],
['label' => 'About', 'url' => ['/site/about']],
['label' => 'Contact', 'url' => ['/site/contact']],
Yii::$app->user->isGuest ?
['label' => 'Login', 'url' => ['/site/login']] :
['label' => 'Logout (' . Yii::$app->user->identity->username . ')',
'url' => ['/site/logout'],
'linkOptions' => ['data-method' => 'post']],
],
]);

我们在本来的基础之上添加了下面这个内容:

 [
'label' => 'Status',
'items' => [
['label' => 'Create', 'url' => ['/status/create']],
],
],

这样之后,刷新一下页面,你就可以看到我们的导航变化了。而且很神奇的是:这里还实现了dropdown menu的功能,这个其实就是使用Bootstrapdropdown menu来实现的。

嗯,这篇文章貌似讲得差不多了,至少我不知道还改讲些什么了,接下来的文章我会尝试讲讲Yii2的数据库相关的内容,先睡觉。

源码会放在 Github:https://github.com/JellyBool/helloYii

Yii2系列教程二:MVC,Forms和Layouts的更多相关文章

  1. CRL快速开发框架系列教程二(基于Lambda表达式查询)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  2. C#微信公众号开发系列教程二(新手接入指南)

    http://www.cnblogs.com/zskbll/p/4093954.html 此系列前面已经更新了两篇博文了,都是微信开发的前期准备工作,现在切入正题,本篇讲解新手接入的步骤与方法,大神可 ...

  3. Android Studio系列教程二--基本设置与运行

    Android Studio系列教程二--基本设置与运行 2014 年 11 月 28 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处! 上面一篇博客,介绍了Studio的 ...

  4. NGUI系列教程二

    接下来我们创建一个Label,NGUI->Open the Widget Wizard,打开widgetTool对话框,在Template中选择Label,确定AddTo右侧选项为panel,点 ...

  5. 黄聪:Microsoft Enterprise Library 5.0 系列教程(二) Cryptography Application Block (高级)

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(二) Cryptography Application Block (高级) 本章介绍的是企业库加密应用程序模块 ...

  6. 黄聪:Microsoft Enterprise Library 5.0 系列教程(二) Cryptography Application Block (初级)

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(二) Cryptography Application Block (初级) 企业库加密应用程序模块提供了2种方 ...

  7. Fastify 系列教程二 (中间件、钩子函数和装饰器)

    Fastify 系列教程: Fastify 系列教程一 (路由和日志) Fastify 系列教程二 (中间件.钩子函数和装饰器) 中间件 Fastify 提供了与 Express 和 Restify ...

  8. webpack4 系列教程(二): 编译 ES6

    今天介绍webpack怎么编译ES6的各种函数和语法.敲黑板:这是webpack4版本哦, 有一些不同于webpack3的地方. >>> 本节课源码 >>> 所有课 ...

  9. Fastify 系列教程二 (中间件、钩子函数和装饰器)

    Fastify 系列教程: Fastify 系列教程一 (路由和日志) Fastify 系列教程二 (中间件.钩子函数和装饰器) Fastify 系列教程三 (验证.序列化和生命周期) Fastify ...

随机推荐

  1. mac air 装ubuntu16.04

    前言 我的mac air购于14年,128GB款.最开始我只是在OS X系统里留出了70GB给ubuntu,然后通过u盘装了ubuntu 14.04,后来又陆续将系统升级到15.04.16.04.各方 ...

  2. (七)计算G711语音的打包长度和RTP里timestamp的增长量

    如何计算G711语音等的打包长度和RTP里timestamp的增长量 一般对于不同的语音有不同的打包周期,而不同的打包周期又对应着不同的timestamp in RTP 那么是如何计算的呢,我们通过G ...

  3. 汉字hash问题(转)

    一.汉字编码的种类 汉字编码中现在主要用到的有三类,包括GBK,GB2312和Big5. 1.GB2312又称国标码,由国家标准总局发布,1981年5月1日实施,通行于大陆.新加坡等地也使用此编码.它 ...

  4. 查看Linux上的CPU核心数、线程数

    grep "physical id" /proc/cpuinfo|sort -u grep "cpu cores" /proc/cpuinfo|uniq gre ...

  5. 存储过程 ----- navicat 创建存储过程

    以下为navicat 创建存储过程步骤图解: 1. 2. 3. 4. 在存储过程正文中是输入一行语句测试用,点击保存 5.输入存储过程名称,点击确定 6.到这来那么问题来了,会提示错误 7.切记存储过 ...

  6. 【C++】多重继承

    1. 多重继承时的二义性 当使用多重继承时,如果多个父类都定义了相同名字的变量,则会出现二义性.解决方法:使用 :: 声明作用域 #include <iostream> using nam ...

  7. Spring ClassPathXmlApplicationContext和FileSystemXmlApplicationContext读取配置文件的方法

    先说:ClassPathXmlApplicationContext 这个类,默认获取的是WEB-INF/classes/下的路径,也就是在myeclipse的src下的路径,所以用这个是获取不到WEB ...

  8. AC日记——逃离僵尸岛 洛谷 P3393

    逃离僵尸岛 思路: spfa: 代码: #include <cstdio> #include <cstring> #include <iostream> #incl ...

  9. 训练指南 UVA - 11354(最小生成树 + 倍增LCA)

    layout: post title: 训练指南 UVA - 11354(最小生成树 + 倍增LCA) author: "luowentaoaa" catalog: true ma ...

  10. 网页截图工具CutyCapt

    网页截图工具CutyCapt   CuteCapt是Kali Linux提供的一款网页截图工具.该工具运行在命令行中,可以将WebKit引擎解析的网页保存为图片.它保存的文件支持矢量图和位图两大类型, ...