このチュートリアルは、Envato Tuts の「Build Your Startup with PHP」シリーズの一部です。このシリーズでは、私のミーティング プランナー アプリを実際の例として使用して、スタートアップの立ち上げをコンセプトから現実に至るまでガイドします。あらゆる段階で、Meeting Planner コードをオープンソースのサンプルとしてリリースし、そこから学ぶことができます。また、スタートアップ関連で発生するビジネス上の問題についても取り上げます。
先週、私は Ajax について深く掘り下げ、会議のスケジュール設定エクスペリエンスを完全に Ajax 対応のモデルに変換し、ページの更新の必要性を排除しました。簡単な要素に焦点を当てて、半分くらい進んでいます。
今日のチュートリアルでは、より多くのトラブルシューティング、調査、デバッグ、ブレインストーミング、および再コーディングが必要な、より複雑なコンテンツ パネルについて説明します。先ほども言いましたが、ベータ版がリリースされるまでこの機能を削除しなければならないかもしれないと思うことがあります。私の個人的な悪夢をご紹介しますので、フォローしてください(今は良くなりました、心配しないでください)。
また、Google の Chrome Developer Console を使用して壊れた領域を特定する方法も紹介します。これは、PHP と JavaScript の間で Ajax を使用する場合に特に困難です。暗いトンネルの先にある光のような。
主催者と参加者が好みを共有し、日時と場所を最終的に選択するのに役立つ気の利いたブートストラップ スイッチをご覧になったことがあるかもしれません。 Ajax アップデート後はこのようにはならないはずですが、これを修正することはこの機能アップデートの重要な部分です:
Meeting Planner をまだ試していない場合は、新しい対話型機能を使用して最初の会議をスケジュールしてください。以下のコメント スレッドに参加しましたので、ぜひご意見をお聞かせください。 Twitter @reifman でもご連絡いただけます。今後のチュートリアルの新しい機能やトピックを提案していただければ特に興味があります。
注意事項として、Meeting Planner のコードはすべて PHP の Yii2 フレームワークを使用して書かれています。 Yii2 についてさらに詳しく知りたい場合は、並行シリーズ「Yii2 によるプログラミング」を参照してください。
まず、Ajax 経由で会議参加者を追加する方法を見てみましょう。
参加者を追加するコードは、前に紹介したものと似ています。ただし、参加者のリストと参加者の ID を表示するすべてのボタンを更新する、少し異なるコードが必要です。
以前は、会議ごとに参加者は 1 人だけでした。次に、グループ ミーティングを有効にし、各参加者に示すボタンのリストを作成しました。
参加者が追加されるたびに、Ajax 経由でリスト全体を更新します。次は、新しいボタンが追加されるたびに
getParticipantButtons() を呼び出す jQuery 関数
addParticipant() です。
リーリー
これは
関数:
リーリー
ParticipantController.php
メソッドへの Ajax 呼び出しを行います:
リーリー
注: 私は、ParticipantController ではなく「ParCon」の略語が好きです。リモートのスタートレックのコマンド ベースのように聞こえるため、または、このスタートアップを自分のマシンでも開発していることを示すためです。自分の会社の責任者。 Ajax 機能に多くの時間を費やしすぎました。
いずれにしても、上記の関数は、更新されたすべての参加者をパネルに再入力します。
次に、一般的に使用される Bootstrap 日時ピッカー ウィジェットの 1 つを使用して、日付と時刻に移りましょう。
日付と時刻を追加する
日付、時刻、場所は、ajax 化で最も複雑な関数です。フォームは Bootstrap ウィジェットまたは Google Maps API を使用していません。その結果、ブートストラップ スイッチ コントローラーが作成されました。これは、Ajax 用に適切に設計または文書化されていないコントローラーでした。
Ajax 経由でのスイッチ コントローラーの起動に関する問題
この問題を最終的に解決する方法について詳しく説明しますが、まず、meet-time/panel.php を見てみましょう:
<?php use yii\helpers\Html; use yii\widgets\ListView; use yii\bootstrap\Collapse; use \kartik\switchinput\SwitchInput; ?> <div id="notifierTime" class="alert-info alert fade in" style="display:none;"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> <?php echo Yii::t('frontend',"We'll automatically notify the organizer when you're done making changes."); ?> </div> <div class="panel panel-default"> <!-- Default panel contents --> <div class="panel-heading" role="tab" id="headingWhen"> <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="#collapseWhen" aria-expanded="true" aria-controls="collapseWhen"><?= Yii::t('frontend','When') ?></a> </h4> <span class="hint-text"> <?php if ($timeProvider->count<=1) { ?> <?= Yii::t('frontend','add one or more dates and times for participants to choose from') ?> <?php } elseif ($timeProvider->count>1) { ?> <?= Yii::t('frontend','are listed times okay?'); ?> <?php } ?> <?php if ($timeProvider->count>1 && ($model->isOrganizer() || $model->meetingSettings['participant_choose_date_time'])) { ?> <?= Yii::t('frontend','you can also choose the time') ?> <?php }?> </span></div><div class="col-lg-2 col-md-2 col-xs-2"><div style="float:right;"> <?php if ($model->isOrganizer() || $model->meetingSettings->participant_add_date_time) { ?> <?= Html::a('', 'javascript:void(0);', ['class' => 'btn btn-primary glyphicon glyphicon-plus','title'=>'Add possible times','id'=>'buttonTime','onclick'=>'showTime();']); ?> <?php } ?> </div> </div> </div> <!-- end row --> </div> <!-- end heading --> <div id="collapseWhen" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingWhen"> <div class="panel-when"> <div class="when-form hidden"> <div id="timeMessage" class="alert-info alert fade in hidden"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> <span id="timeMsg1"><?= Yii::t('frontend','We\'ll automatically notify others when you\'re done making changes.')?></span> <span id="timeMsg2"><?= Yii::t('frontend','Please pick a date and time.')?></span> </div> <div id="addTime" class="hidden"> <!-- hidden add time form --> <?= $this->render('_form', [ 'model' => $meetingTime, ]) ?> </div> </div> <table class="table" id="meeting-time-list" class="hidden"> <?php if ($timeProvider->count>0): ?> <!-- Table --> <?= ListView::widget([ 'dataProvider' => $timeProvider, 'itemOptions' => ['class' => 'item'], 'layout' => '{items}', 'itemView' => '_list', 'viewParams' => ['timezone'=>$timezone,'timeCount'=>$timeProvider->count,'isOwner'=>$isOwner,'participant_choose_date_time'=>$model->meetingSettings['participant_choose_date_time'],'whenStatus'=>$whenStatus], ]) ?> <?php endif; ?> </table> </div> </div> </div>
您会注意到 timeMessage
提供预加载的警报,以便在某些 Ajax 条件下显示,正如我在上一集中回顾的那样。而且,很大程度上,代码开始遵循我在其他面板上使用的相同格式。
我尽可能地尝试以先前的方法为基础,并在ajax化每个内容面板时重用代码结构。
这是 Meeting.js 中的切换面板 JavaScript:
//show the panel function showTime() { if ($('#addTime').hasClass( "hidden")) { $('#addTime').removeClass("hidden"); $('.when-form').removeClass("hidden"); }else { $('#addTime').addClass("hidden"); $('.when-form').addClass("hidden"); } }; function cancelTime() { $('#addTime').addClass("hidden"); $('.when-form').addClass("hidden"); }
当面板出现并且用户提交新的日期时间时,它会调用 addTime()
:
function addTime(id) { start_time = $('#meetingtime-start_time').val(); start = $('#meetingtime-start').val(); if (start_time =='' || start=='') { displayAlert('timeMessage','timeMsg2'); return false; } // ajax submit subject and message $.ajax({ url: $('#url_prefix').val()+'/meeting-time/add', data: { id: id, start_time: encodeURIComponent(start_time), start:encodeURIComponent(start), }, success: function(data) { //$('#meeting-note').val(''); insertTime(id); displayAlert('timeMessage','timeMsg1'); return true; } }); $('#addTime').addClass('hidden'); }
这会调用 MeetingTimeController.php actionAdd()
Ajax 函数:
public function actionAdd($id,$start,$start_time) { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; $timezone = MiscHelpers::fetchUserTimezone(Yii::$app->user->getId()); date_default_timezone_set($timezone); $model = new MeetingTime(); $model->start = urldecode($start); $model->start_time = urldecode($start_time); if (empty($model->start)) { $model->start = Date('M d, Y',time()+3*24*3600); } $model->tz_current = $timezone; $model->duration = 1; $model->meeting_id= $id; $model->suggested_by= Yii::$app->user->getId(); $model->status = MeetingTime::STATUS_SUGGESTED; $selected_time = date_parse($model->start_time); if ($selected_time['hour'] === false) { $selected_time['hour'] =9; $selected_time['minute'] =0; } // convert date time to timestamp $model->start = strtotime($model->start) + $selected_time['hour']*3600+ $selected_time['minute']*60; $model->end = $model->start + (3600*$model->duration); $model->save(); return true; }
当我开始通过 Ajax 添加新的日期时间或地点时,我在尝试重新初始化 Bootstrap Switch 控制器时遇到了困难,我在之前的“调度可用性和选择”一集中就开始使用该控制器。
我重新加载日期时间行,但页面上的所有开关控制器都已损坏。
问题的一部分是 Bootstrap Switch 的 Ajax 重新实例化没有详细记录。在黑暗中尝试了一些事情并在互联网上寻求帮助之后,我终于找到了解决办法。
$("input[name='meeting-time-choice']").map(function(){}
循环遍历每个开关控件,并且 $(this).bootstrapSwitch(property,value)
命令重置控件设置。花了一些时间才找到合适的控件 API。
function insertTime(id) { $.ajax({ url: $('#url_prefix').val()+'/meeting-time/inserttime', data: { id: id, }, type: 'GET', success: function(data) { $("#meeting-time-list").html(data).removeClass('hidden'); $("input[name='time-chooser']").map(function(){ //$(this).bootstrapSwitch(); $(this).bootstrapSwitch('onText','<i class="glyphicon glyphicon-ok"></i> choose'); $(this).bootstrapSwitch('offText','<i class="glyphicon glyphicon-remove"></i>'); $(this).bootstrapSwitch('onColor','success'); $(this).bootstrapSwitch('handleWidth',70); $(this).bootstrapSwitch('labelWidth',10); $(this).bootstrapSwitch('size','small'); }); $("input[name='meeting-time-choice']").map(function(){ //$(this).bootstrapSwitch(); $(this).bootstrapSwitch('onText','<i class="glyphicon glyphicon-thumbs-up"></i> yes'); $(this).bootstrapSwitch('offText','<i class="glyphicon glyphicon-thumbs-down"></i> no'); $(this).bootstrapSwitch('onColor','success'); $(this).bootstrapSwitch('offColor','danger'); $(this).bootstrapSwitch('handleWidth',50); $(this).bootstrapSwitch('labelWidth',10); $(this).bootstrapSwitch('size','small'); }); }, }); refreshSend(); refreshFinalize(); }
基本上,我必须从头开始重新配置每个控件所需的每个属性。这将上面的原始复选框转换回更丰富的开关控件。
在达到这一点之前,我在其他解决方法上浪费了很多时间。 Bootstrap Switch 是一个令人惊叹的控制器,也是 Meeting Planner 易用性的关键部分,但 ajaxifying 几乎让我崩溃。
继续,添加会议地点与添加日期和时间类似,但我想使用此内容面板来深入研究使用 Google Chrome 浏览器开发人员工具对 Ajax 进行故障排除。
正如我之前所说,在 JavaScript 和 PHP 之间调试 Ajax 可能会变得极其混乱和令人沮丧。 Ajax bug 通常很难追踪。
在这种情况下,使用 Google Chrome 浏览器的开发者控制台帮助我突破了空白。
一般来说,使用 Ajax 时,您只是遇到了故障,没有任何迹象表明出了什么问题。
以下是我用来追踪错误的 Chrome 公开的逐步可见性。
通过使用控制台选项卡,我可以看到失败的 GET 请求。这是尝试请求添加会议地点时发生的服务器错误:
这帮助我确定了通过 ajax 请求的具体参数,在本例中为会议 id = 186。
查看网络选项卡还会显示这些调用及其参数:
当您单击特定查询时,您可以看到五个选项卡;这是标题选项卡:
在本例中,预览选项卡突出显示了 Ajax 遇到的 MeetingPlaceController 中的 PHP 错误请求:
您可以看到这变得多么有用 - 特别是考虑到我必须重建大量代码才能实现所有这些调度特点。
以下是网络标签请求会议 ID = 186 地点的另一个示例:
预览标签显示所请求的视图文件不存在或至少不存在不在它应该在的地方:
Google Chrome 的开发者控制台帮助我完成了 Ajax 工作。
谢谢你,谷歌! 今天我什至不会拿我的天才模因来取笑你。
我希望您喜欢关于 Ajax 的这两集以及向快速、高效的会议安排和消除页面刷新的转变。会议安排是 Meeting Planner 的核心和灵魂,因此使其发挥出色至关重要。
私はこのプロセスを通じて個人的に多くのことを学び、その変更はサービスに大きなプラスの影響を与えました。
より迅速なスケジュール設定を試し、会議プランナーを友人と共有してください。いつものように、以下のコメント欄であなたの経験を共有していただければ幸いです。私は常にあなたの提案に興味を持っています。いつでも Twitter @reifman で直接私に連絡してください。
SEC の新しいクラウドファンディング ルールの実装に基づいて、WeFunder で実験を開始しようとしています。ご希望の場合は、プロフィールをフォローしてください。これについては、今後のチュートリアルで詳しく説明します。
「Build Your Startup with PHP」シリーズの今後のチュートリアルをご覧ください。
###関連リンク###ミーティングプランナーのWeFunderページ
以上がスタートアップを構築する: Ajax を使用して会議のスケジュールを簡素化するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。