摘要:重點是在頁面寫入新文本,頁面不能實時顯示。想要了解更多可以參考這篇文章基于驅動的事件廣播下測試實時功能刷新頁面,并觀察數據庫。測試實時創建功能。
說明:本文主要來源于real-time-apps-laravel-5-1-event-broadcasting
本文主要基于Laravel的Model Event介紹該框架的實時通信功能,Laravel模型的生命周期中包含事件:created、creating、saved、saving、updated,updating、deleted、deleting、restored、restoring,同時結合了Pusher包,有關Pusher的注冊和使用相關信息可以參考:基于 Pusher 驅動的 Laravel 事件廣播(上)。同時,作者會將開發過程中的一些截圖和代碼黏上去,提高閱讀效率。
備注:Laravel對Model的CRUD操作都會觸發對應的事件,如create操作會在創建前觸發creating事件,創建后觸發created事件,即Model Event。
先全局安裝composer:
curl -sS https://getcomposer.org/installer | php mv composer.phar /usr/local/bin/composer
新建一個空文件夾,在文件夾下,再使用composer安裝Laravel項目:
composer create-project laravel/laravel mylaravelapp --prefer-dist寫一個TODO APP 寫路由Route
在app/Http/routes.php中寫上資源型路由:
Route::get("/", function () { return view("index"); }); Route::resource("items", "ItemController", ["except" => ["create", "edit"]]);//排除掉create和edit操作寫個Model
先建個遷移文件:
php artisan make:migration create_items_table --create=items
在遷移文件database/migrations/*_create_items_table.php中寫上:
/** * Run the migrations. * * @return void */ public function up() { Schema::create("items", function (Blueprint $table) { $table->increments("id"); $table->string("title"); $table->boolean("isCompleted")->default(false); $table->timestamps(); }); }
新建一個Eloquent Model:
php artisan make:model Item
別忘了配置下數據庫,我用的是MAMP集成環境,數據庫服務是MySQL。數據庫配置主要在config/database.php和.env文件中,在.env文件中寫上對應的host,database,user,password:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_DATABASE=model_event DB_USERNAME=root DB_PASSWORD=model_event寫控制器Controller
首先在項目根目錄下輸入artisan命令創建個ItemController:
php artisan make:controller ItemController
在ItemController中寫上增刪改查:
class ItemController extends Controller { /** * Display a listing of the resource. * * @return Response */ public function index() { $uncompletedItems = Item::where("isCompleted", 0)->get(); $completedItems = Item::where("isCompleted", 1)->get(); $data = ["uncompletedItems" => $uncompletedItems, "completedItems" => $completedItems]; return view("item.index", $data); } /** * Store a newly created resource in storage. * * @return Response */ public function store(Request $request) { $item = new Item; $item->title = $request->title; $item->save(); return response()->json(["id" => $item->id]); } /** * Display the specified resource. * * @param int $id * @return Response */ public function show($id) { $item = Item::find($id); return view("item.show", ["item" => $item]); } /** * Update the specified resource in storage. * * @param int $id * @return Response */ public function update(Request $request, $id) { $item = Item::find($id); $item->isCompleted = (bool) $request->isCompleted; $item->save(); return; } /** * Remove the specified resource from storage. * * @param int $id * @return Response */ public function destroy($id) { $item = Item::find($id); $item->delete(); return; } }寫個View視圖
建個reources/views/index.php:
Todo App {{----}} {{----}} {{----}}{{----}} {{----}} {{----}}Todo App
ItemController控制器中返回兩個子視圖item.index、item.show,在resources/views/item中建兩個:
//item.index
//item.show
一切準備就OK了,我的在MAMP環境輸入路由:http://laravelmodelevent.app:...,新開AB兩個頁面,然后在輸入框里提交文本后:
A頁面輸入后B頁面只有刷新才能看到最新輸入的文本,不能實時顯示,當然,輸入的文本已經保存在model_event.items表里了:
頁面里改變每一個item的checkbox后,該item的狀態將會互換,在UI上顯示也是上下位置互換,具體邏輯可以看views/index.blade.php的JS邏輯,這不是本文的重點,故不詳述。
重點是:在A頁面寫入新文本,B頁面不能實時顯示。這還不是個實時APP。
Real-time App 創建三個廣播事件創建三個廣播事件:
ItemCreated:當新建一個item完成時觸發
ItemUpdated:當更新一個item完成時觸發(isCompleted=0或1)
ItemDeleted:當刪除一個item完成時觸發
在項目根目錄依次輸入:
php artisan make:event ItemCreated php artisan make:event ItemUpdated php artisan make:event ItemDeleted
Laravel事件廣播需要實現ShouldBroadcast接口并且在broadcastOn()方法中寫上廣播頻道:
class ItemCreated extends Event implements ShouldBroadcast { use SerializesModels; public $id; /** * Create a new event instance. * * @return void */ public function __construct(Item $item) { $this->id = $item->id; } /** * Get the channels the event should be broadcast on. * * @return array */ public function broadcastOn() { return ["itemAction"]; } }
class ItemDeleted extends Event implements ShouldBroadcast { use SerializesModels; public $id; /** * Create a new event instance. * * @return void */ public function __construct(Item $item) { $this->id = $item->id; } /** * Get the channels the event should be broadcast on. * * @return array */ public function broadcastOn() { return ["itemAction"]; } }
class ItemUpdated extends Event implements ShouldBroadcast { use SerializesModels; public $id; public $isCompleted; /** * Create a new event instance. * * @return void */ public function __construct(Item $item) { $this->id = $item->id; $this->isCompleted = (bool)$item->isCompleted; } /** * Get the channels the event should be broadcast on. * * @return array */ public function broadcastOn() { return ["itemAction"]; } }創建Model Event
Laravel的Eloquent每一CRUD操作都會觸發Model事件,可以在service provider里監聽這些事件從而觸發新建的三個廣播事件,在AppServiceProvider中:
class AppServiceProvider extends ServiceProvider { /** * Bootstrap any application services. * * @return void */ public function boot() { Item::created(function($item){ event(new ItemCreated($item)); }); Item::deleted(function($item){ event(new ItemDeleted($item)); }); Item::updated(function($item){ event(new ItemUpdated($item)); }); } /** * Register any application services. * * @return void */ public function register() { // } }使用Pusher
Pusher的作用、注冊和安裝可參考:基于 Pusher 驅動的 Laravel 事件廣播(上)
注冊安裝也比較簡單,總之使用Pusher能做個實時APP。
更新resources/views/index.blade.php文件:
...Todo App //引入pusherJS文件 ... $.post( "/items", $(this).serialize(), function( data ) { // addItem(data.id, false);//注銷掉 $( "#title" ).val(""); }); ... $.ajax("/items/" + id, {//進入ItemController::update(),更細下item狀態 data: {"isCompleted": isCompleted}, method: "PATCH", success: function() {//根據狀態變化刪除增加item // removeItem(id);//注銷掉 // addItem(id, isCompleted);//注銷掉 } }); ... $(document).on("click", ".deleteItem", function() { var id = $(this).closest("li").data("id"); $.ajax("/items/" + id, {//進入ItemController::destroy()刪除數據庫中item method: "DELETE", success: function() {//UI刪除該item // removeItem(id);//注銷掉 } }); }); })(jQuery, addItem, removeItem); //新加代碼 var pusher = new Pusher("{{env("PUSHER_KEY")}}"); var itemActionChannel = pusher.subscribe("itemAction"); itemActionChannel.bind("AppEventsItemCreated", function (data) { console.log(data.id); addItem(data.id, false); }); itemActionChannel.bind("AppEventsItemDeleted", function (data) { console.log(data.id); removeItem(data.id); }); itemActionChannel.bind("AppEventsItemUpdated", function (data) { removeItem(data.id); addItem(data.id, data.isCompleted); });
新加代碼主要用pusher對象注冊三個事件廣播的頻道"itemAction",并分別綁定三個事件,成功后回調執行對應的UI操作。想要了解更多可以參考這篇文章:基于 Pusher 驅動的 Laravel 事件廣播(下)
測試實時功能刷新AB頁面,并觀察數據庫model_event.items。
測試實時創建功能。A頁面輸入文本后發現B頁面不用刷新就實時顯示對應內容,且數據庫已經保存剛剛創建的文本:
測試實時更新功能。B頁面點擊狀態更新checkbox后,A頁面該item狀態也實時更新,且數據庫isCompleted字段變為1:
測試實時刪除功能。A頁面點擊刪除按鈕后,B頁面也實時刪除對應的item,且數據庫該item也刪除:
OK,It is working!!!
總結:本節主要利用Laravel的Model Event來創建一個實時WEB APP,挺好玩的,可以玩一玩哦。有問題可留言。嘛,過兩天還想結合Laravel的Container Event容器事件新開篇文章,到時見。
歡迎關注Laravel-China。
RightCapital招聘Laravel DevOps
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21530.html
摘要:提供了一種全新的發送通知的方式。個人理解是可以基于某事件操作觸發一系列的通知任務,而通知方式由通知渠道接管,這樣使得通知或推送邏輯更抽象,更易于管理和重構。在之前,我是利用的來完成這一系列通知。使用的配置文件還是原來的,無需重新配置。 Laravel Notification Laravel 5.3 提供了一種全新的發送通知的方式:Notification 。個人理解是可以基于某事件(...
摘要:說明本文主要學習下的模型觀察者,把一點點經驗分享出來希望對別人能有幫助。模型觀察者這個功能能做很多事情,比如模型更新時發個通知。總結本篇文章主要學了下的模型觀察者,發現這個功能也能使代碼結構更清晰,覺得挺好的。 說明:本文主要學習下Laravel的Model Observer模型觀察者,把一點點經驗分享出來希望對別人能有幫助。同時,作者會將開發過程中的一些截圖和代碼黏上去,提高閱讀效率...
摘要:說明本文主要講述使用作為緩存加快頁面訪問速度。何不用來做緩存,等到該達到一定瀏覽頁面后再刷新下,效率也很高。可作緩存系統隊列系統。 說明:本文主要講述使用Redis作為緩存加快頁面訪問速度。同時,作者會將開發過程中的一些截圖和代碼黏上去,提高閱讀效率。 備注:作者最近在學習github上別人的源碼時,發現好多在計算一篇博客頁面訪問量view_count時都是這么做的:利用Laravel...
摘要:一簡單粗魯用于本地測試路由中定義測試一下修改事件二生成事件和監聽器在定義對應關系生成文件中注入要操作的類中方法注入對應事件類測試一下修改事件最后在模型中添加屬性三利用框架的方法直接在相關中定義測試一下修改事件四定義如果想對多個模型的或事件進 一 、簡單粗魯(用于本地測試) 路由中定義: Event::listen(eloquent.updated: AppPost,function ...
閱讀 2852·2023-04-25 17:59
閱讀 682·2023-04-25 15:05
閱讀 673·2021-11-25 09:43
閱讀 3034·2021-10-12 10:13
閱讀 3537·2021-09-27 13:59
閱讀 3583·2021-09-23 11:21
閱讀 3879·2021-09-08 09:35
閱讀 564·2019-08-29 17:12