Vietnamese (Tiếng Việt) translation by Thai An (you can also view the original English article)

Bài viết này là một phần của loạt bài Xây dựng Khởi nghiệp của bạn với PHP trên Envato Tuts+. Trong loạt bài này, tôi sẽ hướng dẫn bạn tạo một khởi nghiệp từ khái niệm thực tế sử dụng ứng Meeting Planner của tôi như là một ví dụ thực tế. Mỗi bước làm, tôi sẽ cung cấp mã của Meeting Planner như là các ví dụ mã nguồn mở, bạn có thể học hỏi từ đó. Tôi cũng sẽ chỉ ra các vấn đề kinh doanh liên quan đến khởi nghiệp khi chúng xuất hiện.
Giới thiệu
Trong bài hướng dẫn hôm nay, tôi sẽ hướng dẫn bạn đi qua thiết lập khởi đầu của những thay đổi toàn diện đến giao diện các cuộc họp lập kế hoạch. Mục tiêu của tôi là sử dụng Ajax để làm cho tất cả các hoạt động lập lịch trình bình thường nhất có thể mà không có bất kỳ việc làm mới trang nào. Một số khía cạnh điều này hóa ra là đơn giản và những thứ khác khá phức tạp. Trong bài này, tôi sẽ tập trung vào các bộ phận đơn giản: cách cơ bản để cấu trúc các yêu cầu Ajax UX trong ứng dụng Yii dựa trên PHP của bạn.
Trong phần hai, tôi sẽ bao gồm những thứ khó khăn hơn-gỡ lỗi Ajax và tái khởi tạo các widget Bootstrap sau khi khởi tạo nạp trang. Tôi cũng sẽ chia sẻ cách mà tôi sử dụng cửa sổ nhà phát triển trong trình duyệt Google Chrome của Google để giúp tôi nhận biết các mã bị lỗi.
Thành thật mà nói, trong khi các bản cập nhật đầu tiên cũng tốt, tôi gặp rất nhiều lỗi và những khó khăn mà đã có những lúc tôi nghĩ rằng tôi có thể phải từ bỏ mục tiêu cho việc phát hành phiên bản beta.
Kỳ thay, có đường dẫn code mà dường như dẫn tôi đến gần hoàn thành và sau đó nhấn vào một rào cản không thể vượt qua- và tôi đã có thể bắt đầu lại với một cách tiếp cận mới. Cuối cùng, tôi đã có thể hoàn toàn thành công lập lịch một cách đầy đủ thông qua Ajax cho việc phát hành phiên bản beta.
Ngày hôm nay, tôi sẽ hướng dẫn bạn đi qua phần cốt lõi của công việc.
Nếu bạn vẫn chưa thử ứng dụng Meeting Planner, thì hãy tải nó về và lập lịch cho cuộc gặp đầu tiên của bạn với khả năng tương tác mới. Tôi cùng gia vào các chủ đề bình luận dưới đây, vì vậy cho tôi biết những gì bạn nghĩ! Bạn cũng có thể tìm thấy tôi trên Twitter @reifman. Tôi đặc biệt hứng thúà nếu bạn muốn đề nghị tính năng mới hoặc chủ đề cho các hướng dẫn trong tương lai.
Như là một lời nhắc nhở, tất cả các mã cho Meeting Planner viết trong Yii2 Framework cho PHP. Nếu bạn muốn tìm hiểu thêm về Yii2, hãy xem loạt bài song song về Lập trình với Yii2.
Sắp xếp UX lập kế hoạch
Mục tiêu chính của tôi cho giai đoạn này của sản phẩm là thực hiện tất cả các khóa lập kế hoạch các tính năng với Ajax và để loại bỏ các trang web làm mới hiện nay là cần thiết để chỉnh sửa các chủ đề, thêm người tham gia, thêm ngày thời gian và địa điểm và ghi chú.
Nền tảng
Như tôi đã xây dựng được một số Ajax vào trong trang web trước đó, tôi đã có một số ý tưởng những gì sẽ tốt và những gì sẽ là khó khăn.
Tham gia với tôi khi tôi hướng dẫn bạn các phần tử bắt đầu của việc thay đổi ứng lập kế hoạch để sử dụng ajax.
Chỉnh sửa Chủ đề Cuộc gặp

Tôi bắt đầu với việc chỉnh sửa bảng chủ đề cuộc họp vì nó bao gồm một vài trường tĩnh, một đầu vào và một vùng văn bản. Tuy nhiên, trường chủ đề không sử dụng tiện ích jQuery Typeahead. Widget có thể làm phức tạp mọi thứ vì bạn cần có khả năng khởi tạo chúng với Ajax.
Trong trường hợp này, tôi tải trước biểu mẫu bị ẩn và tải thư viện tiện ích cùng với nó. Không có sự phức tạp thực sự với nó. Trong tập tiếp theo, bạn sẽ thấy rằng tiện ích Bootstrap Switch vào ngày giờ và các bảng điều khiển vị trí khiến việc này trở nên khó khăn hơn nhiều.
Tải trước tất cả JavaScript
Vì vậy, để đơn giản hóa ajaxifying mỗi bảng lập kế hoạch (người tham gia, chủ đề, ngày giờ, địa điểm và ghi chú), tôi muốn tải chúng lên phía trước và mở rộng các nội dung ban đầu của meeting.js.
Tôi cũng đã mở rộng định nghĩa MeetingAsset.php để bao gồm nhiều JavaScript hơn:
<?php namespace frontend\assets; use yii\web\AssetBundle; class MeetingAsset extends AssetBundle { public $basePath = '@webroot'; public $baseUrl = '@web'; public $css = [ 'css/bootstrap-combobox.css', ]; public $js = [ 'js/meeting.js', 'js/meeting_time.js', 'js/jstz.min.js', 'js/bootstrap-combobox.js', 'js/create_place.js', ]; public $depends = [ 'yii\web\YiiAsset', 'yii\bootstrap\BootstrapAsset', ]; }
MeetingAsset được tải bởi tệp view.php Meeting:
<?php use yii\helpers\BaseHtml; use yii\helpers\Html; use yii\widgets\DetailView; use yii\widgets\ListView; use common\components\MiscHelpers; use frontend\assets\MeetingAsset; MeetingAsset::register($this);
Đang tải bảng điều khiển chủ đề
Chủ đề và chi tiết cuộc họp là một phần của phần _panel_what.php. Dưới đây, tôi thiết lập nó để được ẩn trên tải trong giới hạn #editWhat
:
<?php if ($model->has_subject || $model->subject == \frontend\models\Meeting::DEFAULT_SUBJECT) { ?> <div id="collapseWhat" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingWhat"> <div class="panel-body"> <div id="showWhat"> <?php if (empty($model->message)) { echo Html::encode($this->title); // note: required because couldn't prevent extra space } else { echo Html::encode($this->title).': '.Html::encode($model->message).' '; } ?> </div> <div id="editWhat" class="hidden"> <?= $this->render('_form', [ 'model' => $model, 'subjects' => $model->defaultSubjectList(), ]) ?> </div> </div> </div> <?php } else { ?>
Tôi nối nút chỉnh sửa (với biểu tượng bút chì) trong _panel_what.php để gọi hàm JavaScript showWhat ()
để hiển thị hoặc ẩn biểu mẫu chỉnh sửa. Đây là mã đó:
<?php if ($model->isOrganizer() && $model->status <= Meeting::STATUS_CONFIRMED) { //['update', 'id' => $model->id] echo Html::a('', 'javascript:void(0);', ['class' => 'btn btn-primary glyphicon glyphicon-pencil', 'title'=>'Edit','onclick'=>'showWhat();']); } ?>
Hàm showWhat ()
từ session.js được hiển thị bên dưới:
// show the message at top of what subject panel function showWhat() { if ($('#showWhat').hasClass( "hidden")) { $('#showWhat').removeClass("hidden"); $('#editWhat').addClass("hidden"); }else { $('#showWhat').addClass("hidden"); $('#editWhat').removeClass("hidden"); $('#meeting-subject').select(); } }; function cancelWhat() { showWhat(); }
Đây là phần đầu của /frontend/views/meeting/_form.php mà nó ẩn và hiển thị. Đây là nơi các trường đầu vào và văn bản xuất hiện:
<?php use yii\helpers\Html; use yii\widgets\ActiveForm; use \kartik\typeahead\TypeaheadBasic; use common\components\MiscHelpers; /* @var $this yii\web\View */ /* @var $model frontend\models\Meeting */ /* @var $form yii\widgets\ActiveForm */ ?> <div class="meeting-form"> <?php $form = ActiveForm::begin(); ?> <div class="row"> <div class="col-md-6"> <?php echo $form->field($model, 'subject')->widget(TypeaheadBasic::classname(), [ 'data' => $subjects, 'options' => ['placeholder' => Yii::t('frontend','what\'s the subject of this meeting?'), 'id'=>'meeting-subject', //'class'=>'input-large form-control' ], 'pluginOptions' => ['highlight'=>true], ]); ?> </div> </div>
Cập nhật các chủ đề và chi tiết cuộc họp thông qua Ajax
Khi người dùng cập nhật biểu mẫu cuộc họp, Ajax sau đây được gọi là:
// meeting subject panel function updateWhat(id) { // ajax submit subject and message $.ajax({ url: $('#url_prefix').val()+'/meeting/updatewhat', data: {id: id, subject: $('#meeting-subject').val(), message: $('#meeting-message').val() }, success: function(data) { $('#showWhat').text($('#meeting-subject').val()); showWhat(); } }); }
Hàm actionUpdatewhat
nằm trong MeetingController.php:
public function actionUpdatewhat($id,$subject='',$message='') { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; if (!Meeting::isAttendee($id,Yii::$app->user->getId())) { return false; } $m=Meeting::findOne($id); $m->subject = $subject; $m->message = $message; $m->update(); return true; }
Thông báo Yii :: $ app-> response-> format = \ yii \ web \ Response :: FORMAT_JSON
; cấu hình phương thức Yii để trả về JSON chứ không phải HTML.
Ngoài ra,hàm Meeting:isAttendee()
là một kiểm tra xác thực để đảm bảo rằng người dùng đã đăng nhập là người tham dự trước khi cập nhật dữ liệu của cuộc họp.
Tôi đã học được gì cho đến nay
Như bạn có thể thấy, phải mất một chút mã để ajaxify tất cả các mảnh.
Một trong những thách thức là một con người cố gắng chuyển đổi giữa nhiều tệp cùng một lúc và hai ngôn ngữ khác nhau. PHP và JavaScript có nhiều cách khác nhau để làm việc. Ví dụ, nối chuỗi được thực hiện với một khoảng thời gian trong PHP và một dấu cộng trong JavaScript. Chuyển đổi nhanh giữa các ngôn ngữ thỉnh thoảng cố gắng tạo chuỗi tham số truy vấn có thể dẫn đến lỗi.
Ngoài ra còn có nhu cầu kiểm tra bảo mật chuyên sâu trong các hàm Ajax dựa trên PHP của tôi. Trong hướng dẫn hôm nay, bạn sẽ thấy sự khởi đầu của điều này, nhưng tôi sẽ phải thêm các kiểm tra kỹ lưỡng hơn trước khi làm cho mã hoàn toàn hoạt động.
Và cuối cùng, như tôi đã đi, tôi đã cố gắng sử dụng lại các ký hiệu và phương pháp tiếp cận cấu trúc để tất cả các mã đều có thành phần và thuật ngữ tương tự với nó — mặc dù làm việc với các phần tử dữ liệu khác nhau.
Gửi ghi chú cuộc họp

Ghi chú cuộc họp cũng là các trường văn bản tĩnh. Tuy nhiên, có thể có một chuỗi ghi chú đang diễn ra cần phải được cập nhật trên trang khi một ghi chú được thêm vào (ví dụ: không chỉ là một chủ đề cuộc họp duy nhất). Và điều quan trọng là phải thông báo cho người dùng rằng chúng tôi sẽ thông báo cho người tham gia về ghi chú.
Ví dụ, tôi đã loại bỏ nút gửi UX trong lập kế hoạch để lập kế hoạch nhanh và hiệu quả. Người dùng Lập kế hoạch cuộc họp mới thường bị nhầm lẫn bởi điều này vì vậy tôi đã thêm cảnh báo để cho họ biết rằng chúng tôi sẽ chăm sóc nó.

Mã hóa Ghi chú qua Ajax
Đầu tiên, có _panel.php cho ghi chú Cuộc họp. Tôi đã xây dựng trước các cảnh báo lỗi ẩn có thể được hiển thị qua jQuery khi cần. Tôi có kế hoạch đơn giản hóa và chuẩn hóa điều này trong tương lai, bao gồm việc sử dụng nội địa hóa cho thư dễ dàng hơn.
Trong ví dụ bên dưới, cả noteMessage1
và noteMessage2
đều được tải dưới dạng ẩn.
<?php use yii\helpers\Html; use yii\bootstrap\Collapse; ?> <div id="noteMessage" class="alert-info alert fade in hidden"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> <span id="noteMessage1"> <?= Yii::t('frontend',"Thanks for your note. We'll automatically share it with other participants.")?></span> <span id="noteMessage2"> <?= Yii::t('frontend','Please be sure to type a note.')?></span> </div> <div class="panel panel-default"> <!-- Default panel contents --> <div class="panel-heading" role="tab" id="headingNote" > <div class="row"> <div class="col-lg-10 col-md-10 col-xs-10"><h4 class="meeting-view"> <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseNote" aria-expanded="true" aria-controls="collapseNote"><?= Yii::t('frontend','Notes') ?></a></h4> <span class="hint-text"><?= Yii::t('frontend','send a message to others') ?></span> </div> <div class="col-lg-2 col-md-2 col-xs-2" > <div style="float:right;"> <?= Html::a('', 'javascript:void(0);', ['class' => 'btn btn-primary glyphicon glyphicon-plus', 'title'=>'Edit','onclick'=>'showNote();']); ?> </div> </div> </div> </div> <div id="collapseNote" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingNote"> <div class="panel-body nopadding"> <div id="editNote" class="hidden"> <?= $this->render('_form', [ 'model' => $model, ]) ?> </div> </div> <div id ="noteThread" class="nopadding"> <?= $this->render('_thread', [ 'model' => $model, 'noteProvider'=>$noteProvider, ]) ?> </div> </div> </div>
Đây là jQuery tìm kiếm một ghi chú trống, hiển thị một lỗi thích hợp hoặc gửi nội dung qua Ajax để yêu cầu cập nhật chuỗi ghi chú và hiển thị cảnh báo thành công:
function updateNote(id) { note = $('#meeting-note').val(); if (note =='') { displayAlert('noteMessage','noteMessage2'); return false; } // ajax submit subject and message $.ajax({ url: $('#url_prefix').val()+'/meeting-note/updatenote', data: {id: id, note: note}, success: function(data) { $('#editNote').addClass("hidden"); $('#meeting-note').val(''); updateNoteThread(id); displayAlert('noteMessage','noteMessage1'); return true; } // to do - error display flash }); } function updateNoteThread(id) { // ajax submit subject and message $.ajax({ url: $('#url_prefix').val()+'/meeting-note/updatethread', data: {id: id}, type: 'GET', success: function(data){ $('#noteThread').html(data); // data['responseText'] }, error: function(error){ } }); }
Một trong những việc cần làm là xử lý các lỗi trong Ajax. Nó không phải dễ dàng để làm điều này và đòi hỏi một kiến trúc khá chi tiết ở khắp mọi nơi để hỗ trợ điều này - bây giờ, tôi đã đi trước mà không xử lý loại lỗi này.
Đây là hàm JavaScript displayAlert ()
mà tôi đã sử dụng lại và được xây dựng dựa trên tất cả các bảng khác nhau và thông báo cảnh báo của chúng:
function displayAlert(alert_id,msg_id) { // which alert box i.e. which panel alert switch (alert_id) { case 'noteMessage': // which msg to display switch (msg_id) { case 'noteMessage1': $('#noteMessage1').removeClass('hidden'); // will share the note $('#noteMessage2').addClass('hidden'); $('#noteMessage').removeClass('hidden').addClass('alert-info').removeClass('alert-danger'); break; case 'noteMessage2': $('#noteMessage1').addClass('hidden'); $('#noteMessage2').removeClass('hidden'); // no note $('#noteMessage').removeClass('hidden').removeClass('alert-info').addClass('alert-danger'); break; } break; case 'participantMessage': // which msg to display $('#participantMessageTell').addClass('hidden'); // will share the note $('#participantMessageError').addClass('hidden'); $('#participantMessageOnlyOne').addClass("hidden"); $('#participantMessageNoEmail').addClass("hidden"); switch (msg_id) { case 'participantMessageTell': $('#participantMessageTell').removeClass('hidden'); // will share the note $('#participantMessage').removeClass('hidden').addClass('alert-info').removeClass('alert-danger'); break; case 'participantMessageError': $('#participantMessageError').removeClass("hidden"); $('#participantMessage').removeClass("hidden").removeClass('alert-info').addClass('alert-danger'); break; case 'participantMessageNoEmail': $('#participantMessageNoEmail').removeClass("hidden"); $('#participantMessage').removeClass("hidden").removeClass('alert-info').addClass('alert-danger'); break; case 'participantMessageOnlyOne': $('#participantMessageOnlyOne').removeClass("hidden"); $('#participantMessage').removeClass("hidden").removeClass('alert-info').addClass('alert-danger'); break; } break; case 'placeMessage': // which msg to display $('#placeMsg1').addClass('hidden'); // will share the note $('#placeMsg2').addClass('hidden'); // will share the note $('#placeMsg3').addClass('hidden'); // will share the note switch (msg_id) { case 'placeMsg1': $('#placeMsg1').removeClass('hidden'); // will share the note $('#placeMessage').removeClass('hidden').addClass('alert-info').removeClass('alert-danger'); break; case 'placeMsg2': $('#placeMsg2').removeClass('hidden'); // will share the note $('#placeMessage').removeClass('hidden').removeClass('alert-info').addClass('alert-danger'); break; } break; case 'timeMessage': // which msg to display $('#timeMsg1').addClass('hidden'); // will share the note $('#timeMsg2').addClass('hidden'); // will share the note //$('#timeMsg3').addClass('hidden'); // will share the note switch (msg_id) { case 'timeMsg1': $('#timeMsg1').removeClass('hidden'); // will share the note $('#timeMessage').removeClass('hidden').addClass('alert-info').removeClass('alert-danger'); break; case 'timeMsg2': $('#timeMsg2').removeClass('hidden'); // will share the note $('#timeMessage').removeClass('hidden').removeClass('alert-info').addClass('alert-danger'); break; } break; } }
Cập nhật Chủ đề Ghi chú
Khi người dùng gửi một ghi chú mới, hành động MeetingNoteController.phpUpdatethread ()
được gọi thông qua Ajax. Đây là PHP:
public function actionUpdatethread($id) { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $m=Meeting::findOne($id); $noteProvider = new ActiveDataProvider([ 'query' => MeetingNote::find()->where(['meeting_id'=>$id]), 'sort'=> ['defaultOrder' => ['created_at'=>SORT_DESC]], ]); $result = $this->renderPartial('_thread', [ 'model' =>$m, 'noteProvider' => $noteProvider, ]); return $result; }
Tôi đã thử nghiệm vào những thời điểm chỉ đơn giản là trả về mục mới nhất của nội dung (tức là ghi chú mới nhất) và chèn ở trên các mục trước. Tuy nhiên, điều này tỏ ra phiền hà, đặc biệt là với thời gian ngày và những nơi hiển thị trong hàng bảng.
Bây giờ, tôi thay thế toàn bộ chuỗi nội dung đã cập nhật và thay thế toàn bộ bảng thông qua Ajax. Đây là phần _thread.php tải tất cả các ghi chú, bao gồm cả ghi chú mới:
<?php use yii\widgets\ListView; use yii\helpers\Html; if ($timeProvider->count>0): ?> <table class="table"> <?= ListView::widget([ 'dataProvider' => $timeProvider, 'layout' => '{items}', 'itemView' => '_list', ]) ?> </table> <?php endif; ?>
Tôi hy vọng đó là đủ để nghiên cứu và thử cho ngày hôm nay.
Tôi đã dành khoảng 5 đến 7 ngày dài mã hóa bao gồm cả một người hoàn toàn để hoàn thành tất cả mã đằng sau cả tập này và tập tiếp theo. Tôi đã không kéo một tất cả-nighter trong năm. Tuy nhiên, kết quả đã được truyền cảm hứng.
Vậy, Tiếp theo là gì?
Tôi hy vọng sẽ rất hữu ích khi xem các khái niệm cơ bản về phát triển Ajax cho Yii và PHP. Tôi chắc chắn đã học được rất nhiều thông qua quá trình này, và những thay đổi đã làm cho các cuộc họp lập kế hoạch cực kỳ nhanh hơn và dễ dàng hơn so với trước đây.
Trong tập tiếp theo, tôi sẽ đề cập đến các tính năng còn lại thêm thời gian và địa điểm ngày và sử dụng công cụ gỡ lỗi Trình duyệt Google Chrome để hỗ trợ tôi.
Trong khi bạn đang đợi tập tiếp theo, hãy lên lịch cuộc họp đầu tiên của bạn và thử các tính năng lập kế hoạch Ajax. Ngoài ra, tôi sẽ đánh giá cao nếu bạn chia sẻ kinh nghiệm của bạn dưới đây trong các ý kiến, và tôi luôn luôn quan tâm đến đề xuất của bạn. Bạn cũng có thể liên hệ trực tiếp với tôi trên Twitter @reifman.
Bản phát hành xem trước Công cụ lập kế hoạch cuộc họp hiện đang hoạt động. Không sao để chia sẻ nó với bạn bè và đồng nghiệp của bạn để sử dụng.
Cuối cùng, tôi bắt đầu thử nghiệm với WeFunder dựa trên việc thực hiện các quy tắc huy động vốn từ cộng đồng mới của SEC. Bạn có thể theo dõi hồ sơ của chúng tôi ở đó nếu bạn muốn. Tôi cũng sẽ viết thêm về điều này trong một hướng dẫn trong tương lai.
Xem các hướng dẫn sắp tới trong loạt bài Xây dựng Khởi nghiệp Với PHP của bạn.
Liên kết liên quan
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post