- PVSM.RU - https://www.pvsm.ru -
Здравствуйте, уважаемые Хабровчане! Решил поделиться с вами довольно простым криворуким приёмом, как за 10 минут "поднять" чатик на "голом" yii2 с помощью pjax. Кому интересно про что речь, добро пожаловать под кат.
Думаю что большинство читателей, знакомых с yii2 [1], также знакомы и с технологией pjax [2].
От БД нам нужна всего 1 таблица с сообщениями, создадим её в свойственной yii манере, с помощью миграции:
$ ./yii migrate/create init
use yiidbMigration;
class m160923_115323_init extends Migration
{
public function up()
{
$this->createTable('message', [
'id' => $this->primaryKey(),
'from' => $this->integer()->notNull(),
'to' => $this->integer()->notNull(),
'text' => $this->text()->notNull()
]);
}
public function down()
{
$this->dropTable('message');
}
}
На данном этапе можно сразу описать модель сообщения с довольно важным методом, с помощью которого мы в дальнейшем будет получать экземпляр ActiveQuery для формирования самого чата:
namespace appmodels;
use yiidbActiveQuery;
use yiidbActiveRecord;
/**
* @property int $id
* @property int $from
* @property int $to
* @property string $text
*/
class Message extends ActiveRecord
{
public function rules()
{
return [
[['from', 'to', 'text'], 'required'],
[['from', 'to'], 'integer'],
['text', 'string']
];
}
/**
* @param int $from
* @param int $to
* @return ActiveQuery
*/
public static function findMessages($from, $to)
{
return self::find()
->where(['from' => $from])
->orWhere(['from' => $to, 'to' => $from]);
}
}
вот собственно и всё, что нам потребуется от БД.
Контроллер у нас будет состоять всего из одного "экшна":
namespace appcontrollers;
use appmodelsMessage;
use Yii;
use yiifiltersAccessControl;
use yiihelpersVarDumper;
use yiiwebController;
class ChatController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['@'],
]
],
]
];
}
public function actionIndex($id)
{
$currentUserId = Yii::$app->user->identity->getId();
$messagesQuery = Message::findMessages($currentUserId, $id);
$message = new Message([
'from' => $currentUserId,
'to' => $id
]);
if ($message->load(Yii::$app->request->post()) && $message->validate()) {
$message->save();
$message = new Message([
'from' => $currentUserId
]);
if (Yii::$app->request->isPjax) {
return $this->renderAjax('_chat', compact('messagesQuery', 'message'));
}
}
if (Yii::$app->request->isPjax) {
return $this->renderAjax('_list', compact('messagesQuery', 'message'));
}
return $this->render('chat', compact('messagesQuery', 'message'));
}
}
Постараюсь пояснить, что происходит в "экшне":
А вот тут, по моему мнению, самое интересное. Для начала постараюсь пояснить логику обновления "чатика" при помощи pjax:
В нашем случае нам нужно:
<?php
/**
* @var yiiwebView $this
* @var appmodelsMessage $message
* @var yiidbActiveQuery $messagesQuery
*/
?>
<?php yiiwidgetsPjax::begin([
'timeout' => 3000,
'enablePushState' => false,
'linkSelector' => false,
'formSelector' => '.pjax-form'
]) ?>
<?= $this->render('_chat', compact('messagesQuery', 'message')) ?>
<?php yiiwidgetsPjax::end() ?>
<?php $this->registerJs(<<<JS
function updateList() {
$.pjax.reload({container: '#list-messages'});
}
setInterval(updateList, 1000);
JS
) ?>
<?php
/**
* @var yiiwebView $this
* @var appmodelsMessage $message
* @var yiidbActiveQuery $messagesQuery
*/
?>
<?php yiiwidgetsPjax::begin([
'id' => 'list-messages',
'enablePushState' => false,
'formSelector' => false,
'linkSelector' => false
]) ?>
<?= $this->render('_list', compact('messagesQuery')) ?>
<?php yiiwidgetsPjax::end() ?>
<?php yiiwidgetsActiveForm::begin(['options' => ['class' => 'pjax-form']]) ?>
<?= yiibootstrapHtml::activeTextarea($message, 'text') ?>
<?= yiihelpersHtml::submitButton('Отправить') ?>
<?php yiiwidgetsActiveForm::end() ?>
<?php
/**
* @var yiiwebView $this
* @var yiidbActiveQuery $messagesQuery
*/
?>
<?= yiiwidgetsListView::widget([
'itemView' => '_row',
'layout' => '{items}',
'dataProvider' => new yiidataActiveDataProvider([
'query' => $messagesQuery,
'pagination' => false
])
]) ?>
<?php
/**
* @var yiiwebView $this
* @var appmodelsMessage $model
*/
?>
<div class="row">
<div class="col-md-3"><?= $model->from ?></div>
<div class="col-md-9"><?= $model->text ?></div>
</div>
Автор: sluchainiyznak
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ajax/191782
Ссылки в тексте:
[1] yii2: https://github.com/yiisoft/yii2
[2] pjax: https://github.com/defunkt/jquery-pjax
[3] Источник: https://habrahabr.ru/post/310888/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.