{"id":77295,"date":"2024-08-29T16:50:01","date_gmt":"2024-08-29T09:50:01","guid":{"rendered":"https:\/\/itviec.com\/blog\/?p=77295"},"modified":"2024-08-29T16:50:01","modified_gmt":"2024-08-29T09:50:01","slug":"bloc-flutter-la-gi","status":"publish","type":"post","link":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/","title":{"rendered":"BloC Flutter: H\u01b0\u1edbng d\u1eabn chi ti\u1ebft c\u00e1ch s\u1eed d\u1ee5ng BloC trong Flutter"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">N\u1ed9i dung b\u00e0i vi\u1ebft<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#Khai_niem_co_ban_can_biet_khi_tim_hieu_ve_BloC_Flutter\" >Kh\u00e1i ni\u1ec7m c\u01a1 b\u1ea3n c\u1ea7n bi\u1ebft khi t\u00ecm hi\u1ec3u v\u1ec1 BloC Flutter<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#So_do_hoat_dong_cua_BloC_Flutter\" >S\u01a1 \u0111\u1ed3 ho\u1ea1t \u0111\u1ed9ng c\u1ee7a BloC Flutter<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#Uu_diem_cua_BloC_Pattern\" >\u01afu \u0111i\u1ec3m c\u1ee7a BloC Pattern<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#Cach_trien_khai_BloC_Flutter\" >C\u00e1ch tri\u1ec3n khai BloC Flutter<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#Vi_du_ung_dung_thuc_te_cua_BloC_Flutter\" >V\u00ed d\u1ee5 \u1ee9ng d\u1ee5ng th\u1ef1c t\u1ebf c\u1ee7a BloC Flutter<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#Thuc_hanh_BloC_Flutter_nang_cao\" >Th\u1ef1c h\u00e0nh BloC Flutter n\u00e2ng cao<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#Cac_cau_hoi_thuong_gap_ve_BloC_Flutter\" >C\u00e1c c\u00e2u h\u1ecfi th\u01b0\u1eddng g\u1eb7p v\u1ec1 BloC Flutter<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#Tong_ket_BloC_Flutter\" >T\u1ed5ng k\u1ebft BloC Flutter<\/a><\/li><\/ul><\/nav><\/div>\n<p><em><strong>B\u00e0i vi\u1ebft &#8220;BloC Flutter&#8221; sau \u0111\u00e2y gi\u1edbi thi\u1ec7u m\u00f4 h\u00ecnh qu\u1ea3n l\u00fd tr\u1ea1ng th\u00e1i BloC (Business Logic Component) trong c\u1ed9ng \u0111\u1ed3ng Flutter. B\u00e0i vi\u1ebft gi\u1ea3i th\u00edch kh\u00e1i ni\u1ec7m BloC, c\u00e1ch t\u00e1ch bi\u1ec7t logic nghi\u1ec7p v\u1ee5 kh\u1ecfi giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng v\u00e0 t\u1ea7m quan tr\u1ecdng c\u1ee7a \u0111i\u1ec1u n\u00e0y trong ph\u00e1t tri\u1ec3n \u1ee9ng d\u1ee5ng. \u0110\u1ed3ng th\u1eddi, n\u00eau r\u00f5 l\u1ee3i \u00edch c\u1ee7a BloC v\u00e0 so s\u00e1nh v\u1edbi c\u00e1c m\u00f4 h\u00ecnh kh\u00e1c nh\u01b0 Provider, Redux v\u00e0 Riverpod, ch\u1ec9 ra \u01b0u nh\u01b0\u1ee3c \u0111i\u1ec3m c\u1ee7a t\u1eebng m\u00f4 h\u00ecnh \u0111\u1ec3 gi\u00fap b\u1ea1n ch\u1ecdn gi\u1ea3i ph\u00e1p ph\u00f9 h\u1ee3p.<\/strong><\/em><\/p>\n<p><span style=\"font-weight: 400;\">\u0110\u1ecdc b\u00e0i vi\u1ebft n\u00e0y \u0111\u1ec3 hi\u1ec3u th\u00eam v\u1ec1:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">C\u00e1c kh\u00e1i ni\u1ec7m c\u01a1 b\u1ea3n trong BloC Flutter<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">C\u00e1ch s\u1eed d\u1ee5ng BloC\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">V\u00ed d\u1ee5 s\u1eed d\u1ee5ng BloC trong th\u1ef1c t\u1ebf<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Th\u1ef1c h\u00e0nh n\u00e2ng cao v\u1edbi BloC\u00a0<\/span><\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Khai_niem_co_ban_can_biet_khi_tim_hieu_ve_BloC_Flutter\"><\/span><strong>Kh\u00e1i ni\u1ec7m c\u01a1 b\u1ea3n c\u1ea7n bi\u1ebft khi t\u00ecm hi\u1ec3u v\u1ec1 BloC Flutter<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><strong>BloC Flutter l\u00e0 g\u00ec?<\/strong><\/h3>\n<p><b>\u0110\u1ecbnh ngh\u0129a: <\/b><span style=\"font-weight: 400;\">BloC (Business Logic Component) l\u00e0 m\u1ed9t gi\u1ea3i ph\u00e1p qu\u1ea3n l\u00fd tr\u1ea1ng th\u00e1i gi\u00fap t\u00e1ch bi\u1ec7t logic nghi\u1ec7p v\u1ee5 kh\u1ecfi m\u00e3 giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng (UI) trong \u1ee9ng d\u1ee5ng Flutter. BloC khuy\u1ebfn kh\u00edch c\u00e1ch ti\u1ebfp c\u1eadn ph\u1ea3n \u1ee9ng, gi\u00fap m\u00e3 c\u1ee7a b\u1ea1n d\u1ec5 b\u1ea3o tr\u00ec v\u00e0 m\u1edf r\u1ed9ng h\u01a1n.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">BloC l\u00e0 vi\u1ebft t\u1eaft c\u1ee7a Business Logic Component. \u0110\u00e2y l\u00e0 m\u1ed9t m\u1eabu thi\u1ebft k\u1ebf do Google t\u1ea1o ra \u0111\u1ec3 t\u00e1ch bi\u1ec7t logic nghi\u1ec7p v\u1ee5 kh\u1ecfi UI trong \u1ee9ng d\u1ee5ng Flutter, s\u1eed d\u1ee5ng streams \u0111\u1ec3 qu\u1ea3n l\u00fd lu\u1ed3ng d\u1eef li\u1ec7u v\u00e0 s\u1ef1 ki\u1ec7n.<\/span><\/p>\n<p><b>Vai tr\u00f2:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">X\u1eed l\u00fd logic nghi\u1ec7p v\u1ee5: BloC th\u1ef1c hi\u1ec7n c\u00e1c ph\u00e9p t\u00ednh, g\u1ecdi API, ho\u1eb7c th\u1ef1c hi\u1ec7n c\u00e1c t\u00e1c v\u1ee5 kh\u00e1c \u0111\u1ec3 c\u1eadp nh\u1eadt state.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Qu\u1ea3n l\u00fd lu\u1ed3ng d\u1eef li\u1ec7u: BloC \u0111i\u1ec1u ph\u1ed1i lu\u1ed3ng d\u1eef li\u1ec7u gi\u1eefa giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng v\u00e0 c\u00e1c l\u1edbp kh\u00e1c trong \u1ee9ng d\u1ee5ng.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">T\u00e1ch bi\u1ec7t m\u1ed1i quan t\u00e2m: BloC gi\u00fap t\u00e1ch bi\u1ec7t logic nghi\u1ec7p v\u1ee5 kh\u1ecfi giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng, l\u00e0m cho code tr\u1edf n\u00ean r\u00f5 r\u00e0ng v\u00e0 d\u1ec5 b\u1ea3o tr\u00ec h\u01a1n.<\/span><\/li>\n<\/ul>\n<p><b>V\u00ed d\u1ee5:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">\u1ee8ng d\u1ee5ng danh s\u00e1ch vi\u1ec7c l\u00e0m: BloC s\u1ebd x\u1eed l\u00fd c\u00e1c event nh\u01b0 th\u00eam vi\u1ec7c l\u00e0m m\u1edbi, x\u00f3a vi\u1ec7c l\u00e0m, c\u1eadp nh\u1eadt tr\u1ea1ng th\u00e1i ho\u00e0n th\u00e0nh c\u1ee7a vi\u1ec7c l\u00e0m.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">\u1ee8ng d\u1ee5ng \u0111\u0103ng nh\u1eadp: BloC s\u1ebd x\u1eed l\u00fd c\u00e1c event nh\u01b0 \u0111\u0103ng nh\u1eadp, \u0111\u0103ng xu\u1ea5t, l\u1ea5y th\u00f4ng tin ng\u01b0\u1eddi d\u00f9ng.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">C\u00e1c th\u00e0nh ph\u1ea7n trong BloC bao g\u1ed3m nh\u01b0 Event (s\u1ef1 ki\u00ean), State (tr\u1ea1ng th\u00e1i), Stream (D\u00f2ng d\u1eef\u00a0 li\u1ec7u), c\u00e1c th\u00e0nh ph\u1ea7n n\u00e0y ho\u1ea1t \u0111\u1ed9ng k\u1ebft h\u1ee3p v\u1edbi nhau cho ta kh\u00e1i ni\u1ec7m c\u01a1 b\u1ea3n v\u1ec1 BloC \u0111\u1ec3 t\u00ecm hi\u1ec3u k\u1ef9 h\u01a1n c\u00e1c th\u00e0nh ph\u1ea7n trong BloC.<\/span><\/p>\n<h3><b>Kh\u00e1i ni\u1ec7m Event trong BloC Flutter<\/b><\/h3>\n<p><b>Event<\/b><span style=\"font-weight: 400;\"> trong ki\u1ebfn tr\u00fac BloC l\u00e0 m\u1ed9t \u0111\u1ed1i t\u01b0\u1ee3ng \u0111\u01a1n gi\u1ea3n m\u00f4 t\u1ea3 m\u1ed9t h\u00e0nh \u0111\u1ed9ng ho\u1eb7c s\u1ef1 ki\u1ec7n m\u00e0 ng\u01b0\u1eddi d\u00f9ng ho\u1eb7c h\u1ec7 th\u1ed1ng k\u00edch ho\u1ea1t. N\u00f3 \u0111\u00f3ng vai tr\u00f2 l\u00e0 m\u1ed9t th\u00f4ng \u0111i\u1ec7p g\u1eedi \u0111\u1ebfn BloC \u0111\u1ec3 y\u00eau c\u1ea7u th\u1ef1c hi\u1ec7n m\u1ed9t h\u00e0nh \u0111\u1ed9ng c\u1ee5 th\u1ec3.<\/span><\/p>\n<p><b>T\u00ednh ch\u1ea5t v\u00e0 vai tr\u00f2 c\u1ee7a Event:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>\u0110\u01a1n gi\u1ea3n:<\/b><span style=\"font-weight: 400;\"> Event th\u01b0\u1eddng \u0111\u01b0\u1ee3c \u0111\u1ecbnh ngh\u0129a l\u00e0 m\u1ed9t class ho\u1eb7c enum v\u1edbi c\u00e1c tr\u01b0\u1eddng d\u1eef li\u1ec7u c\u1ea7n thi\u1ebft \u0111\u1ec3 m\u00f4 t\u1ea3 s\u1ef1 ki\u1ec7n.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Kh\u00f4ng ch\u1ee9a logic:<\/b><span style=\"font-weight: 400;\"> Event ch\u1ec9 ch\u1ee9a th\u00f4ng tin v\u1ec1 s\u1ef1 ki\u1ec7n, kh\u00f4ng ch\u1ee9a b\u1ea5t k\u1ef3 logic x\u1eed l\u00fd n\u00e0o.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>C\u1ea7u n\u1ed1i:<\/b><span style=\"font-weight: 400;\"> Event \u0111\u00f3ng vai tr\u00f2 l\u00e0 c\u1ea7u n\u1ed1i gi\u1eefa giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng (UI) v\u00e0 logic nghi\u1ec7p v\u1ee5 (BloC). Khi ng\u01b0\u1eddi d\u00f9ng th\u1ef1c hi\u1ec7n m\u1ed9t h\u00e0nh \u0111\u1ed9ng tr\u00ean giao di\u1ec7n (v\u00ed d\u1ee5: nh\u1ea5n n\u00fat, nh\u1eadp li\u1ec7u), m\u1ed9t event t\u01b0\u01a1ng \u1ee9ng s\u1ebd \u0111\u01b0\u1ee3c t\u1ea1o ra v\u00e0 g\u1eedi \u0111\u1ebfn BloC.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>K\u00edch ho\u1ea1t state:<\/b><span style=\"font-weight: 400;\"> Khi BloC nh\u1eadn \u0111\u01b0\u1ee3c m\u1ed9t event, n\u00f3 s\u1ebd th\u1ef1c hi\u1ec7n c\u00e1c x\u1eed l\u00fd c\u1ea7n thi\u1ebft v\u00e0 ph\u00e1t ra m\u1ed9t state m\u1edbi \u0111\u1ec3 c\u1eadp nh\u1eadt giao di\u1ec7n.<\/span><\/li>\n<\/ul>\n<p><b>V\u00ed d\u1ee5: <\/b><span style=\"font-weight: 400;\">Gi\u1ea3 s\u1eed ch\u00fang ta c\u00f3 m\u1ed9t \u1ee9ng d\u1ee5ng \u0111\u01a1n gi\u1ea3n \u0111\u1ec3 \u0111\u1ebfm s\u1ed1 l\u1ea7n nh\u1ea5n n\u00fat. Ta c\u00f3 th\u1ec3 \u0111\u1ecbnh ngh\u0129a c\u00e1c event nh\u01b0 sau:<\/span><\/p>\n<pre>Dart\r\n\r\nclass IncrementEvent extends Counter Event {}\r\nclass DecrementEvent extends Counter Event {}<\/pre>\n<p><span style=\"font-weight: 400;\">IncrementEvent<\/span><span style=\"font-weight: 400;\"> v\u00e0 <\/span><span style=\"font-weight: 400;\">DecrementEvent<\/span><span style=\"font-weight: 400;\"> \u0111\u1ea1i di\u1ec7n cho hai h\u00e0nh \u0111\u1ed9ng: t\u0103ng v\u00e0 gi\u1ea3m s\u1ed1 \u0111\u1ebfm.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">S\u01a1 \u0111\u1ed3 ho\u1ea1t \u0111\u1ed9ng:<\/span><\/p>\n<pre>flowchart LR\r\n    A(UI) --&gt; B(Event)\r\n    B --&gt; C(Bloc)<\/pre>\n<p><b>Gi\u1ea3i th\u00edch:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Ng\u01b0\u1eddi d\u00f9ng t\u01b0\u01a1ng t\u00e1c v\u1edbi giao di\u1ec7n (UI), t\u1ea1o ra m\u1ed9t event (v\u00ed d\u1ee5: nh\u1ea5n n\u00fat &#8220;T\u0103ng&#8221;).<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Event \u0111\u01b0\u1ee3c g\u1eedi \u0111\u1ebfn BloC.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">BloC nh\u1eadn \u0111\u01b0\u1ee3c event v\u00e0 th\u1ef1c hi\u1ec7n c\u00e1c x\u1eed l\u00fd t\u01b0\u01a1ng \u1ee9ng.<\/span><\/li>\n<\/ul>\n<p><b>T\u1ea1i sao c\u1ea7n Event?<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>T\u00e1ch bi\u1ec7t m\u1ed1i quan t\u00e2m:<\/b><span style=\"font-weight: 400;\"> T\u00e1ch bi\u1ec7t vi\u1ec7c m\u00f4 t\u1ea3 m\u1ed9t h\u00e0nh \u0111\u1ed9ng (event) v\u1edbi vi\u1ec7c x\u1eed l\u00fd h\u00e0nh \u0111\u1ed9ng \u0111\u00f3 (BloC) gi\u00fap code tr\u1edf n\u00ean r\u00f5 r\u00e0ng v\u00e0 d\u1ec5 b\u1ea3o tr\u00ec h\u01a1n.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>D\u1ec5 m\u1edf r\u1ed9ng:<\/b><span style=\"font-weight: 400;\"> Khi c\u1ea7n th\u00eam c\u00e1c t\u00ednh n\u0103ng m\u1edbi, ch\u00fang ta ch\u1ec9 c\u1ea7n \u0111\u1ecbnh ngh\u0129a th\u00eam c\u00e1c event m\u1edbi m\u00e0 kh\u00f4ng c\u1ea7n s\u1eeda \u0111\u1ed5i qu\u00e1 nhi\u1ec1u code \u1edf c\u00e1c th\u00e0nh ph\u1ea7n kh\u00e1c.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>D\u1ec5 ki\u1ec3m th\u1eed:<\/b><span style=\"font-weight: 400;\"> Vi\u1ec7c ki\u1ec3m th\u1eed c\u00e1c tr\u01b0\u1eddng h\u1ee3p kh\u00e1c nhau c\u1ee7a \u1ee9ng d\u1ee5ng tr\u1edf n\u00ean d\u1ec5 d\u00e0ng h\u01a1n khi ch\u00fang ta c\u00f3 th\u1ec3 t\u1ea1o ra c\u00e1c event \u0111\u1ec3 m\u00f4 ph\u1ecfng c\u00e1c h\u00e0nh \u0111\u1ed9ng c\u1ee7a ng\u01b0\u1eddi d\u00f9ng.<\/span><\/li>\n<\/ul>\n<p><b>T\u00f3m l\u1ea1i,<\/b><span style=\"font-weight: 400;\"> Event l\u00e0 m\u1ed9t kh\u00e1i ni\u1ec7m quan tr\u1ecdng trong ki\u1ebfn tr\u00fac BloC. N\u00f3 gi\u00fap ch\u00fang ta x\u00e2y d\u1ef1ng c\u00e1c \u1ee9ng d\u1ee5ng Flutter m\u1ed9t c\u00e1ch c\u00f3 c\u1ea5u tr\u00fac, d\u1ec5 hi\u1ec3u v\u00e0 d\u1ec5 b\u1ea3o tr\u00ec.<\/span><\/p>\n<h3><strong>State: Tr\u1ea1ng th\u00e1i<\/strong><\/h3>\n<p><b>\u0110\u1ecbnh ngh\u0129a: <\/b><span style=\"font-weight: 400;\">State l\u00e0 m\u1ed9t \u0111\u1ed1i t\u01b0\u1ee3ng m\u00f4 t\u1ea3 tr\u1ea1ng th\u00e1i hi\u1ec7n t\u1ea1i c\u1ee7a m\u1ed9t ph\u1ea7n ho\u1eb7c to\u00e0n b\u1ed9 \u1ee9ng d\u1ee5ng t\u1ea1i m\u1ed9t th\u1eddi \u0111i\u1ec3m c\u1ee5 th\u1ec3. Trong ng\u1eef c\u1ea3nh c\u1ee7a BloC, state \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng \u0111\u1ec3 ph\u1ea3n \u00e1nh nh\u1eefng thay \u0111\u1ed5i trong d\u1eef li\u1ec7u ho\u1eb7c giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng.<\/span><\/p>\n<p><b>Vai tr\u00f2:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">C\u1eadp nh\u1eadt giao di\u1ec7n: Khi state thay \u0111\u1ed5i, c\u00e1c widget s\u1ebd t\u1ef1 \u0111\u1ed9ng rebuild \u0111\u1ec3 ph\u1ea3n \u00e1nh nh\u1eefng thay \u0111\u1ed5i \u0111\u00f3.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">L\u01b0u tr\u1eef d\u1eef li\u1ec7u: State c\u00f3 th\u1ec3 l\u01b0u tr\u1eef c\u00e1c d\u1eef li\u1ec7u c\u1ea7n thi\u1ebft cho vi\u1ec7c hi\u1ec3n th\u1ecb v\u00e0 t\u01b0\u01a1ng t\u00e1c v\u1edbi \u1ee9ng d\u1ee5ng.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Truy\u1ec1n d\u1eef li\u1ec7u: State \u0111\u01b0\u1ee3c truy\u1ec1n t\u1eeb BloC \u0111\u1ebfn c\u00e1c widget \u0111\u1ec3 c\u1eadp nh\u1eadt giao di\u1ec7n.<\/span><\/li>\n<\/ul>\n<p><b>V\u00ed d\u1ee5:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">\u1ee8ng d\u1ee5ng danh s\u00e1ch vi\u1ec7c l\u00e0m: State c\u00f3 th\u1ec3 ch\u1ee9a danh s\u00e1ch c\u00e1c c\u00f4ng vi\u1ec7c, tr\u1ea1ng th\u00e1i t\u1ea3i d\u1eef li\u1ec7u (\u0111ang t\u1ea3i, \u0111\u00e3 t\u1ea3i, l\u1ed7i), tr\u1ea1ng th\u00e1i ch\u1ecdn m\u1ed9t c\u00f4ng vi\u1ec7c.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">\u1ee8ng d\u1ee5ng \u0111\u0103ng nh\u1eadp: State c\u00f3 th\u1ec3 ch\u1ee9a th\u00f4ng tin ng\u01b0\u1eddi d\u00f9ng \u0111\u00e3 \u0111\u0103ng nh\u1eadp, tr\u1ea1ng th\u00e1i \u0111\u0103ng nh\u1eadp (\u0111\u00e3 \u0111\u0103ng nh\u1eadp, ch\u01b0a \u0111\u0103ng nh\u1eadp), th\u00f4ng b\u00e1o l\u1ed7i khi \u0111\u0103ng nh\u1eadp.<\/span><\/li>\n<\/ul>\n<h3><strong>Stream: D\u00f2ng d\u1eef li\u1ec7u<\/strong><\/h3>\n<p><b>\u0110\u1ecbnh ngh\u0129a: <\/b><span style=\"font-weight: 400;\">Stream l\u00e0 m\u1ed9t chu\u1ed7i c\u00e1c d\u1eef li\u1ec7u ph\u00e1t ra theo th\u1eddi gian. Trong ng\u1eef c\u1ea3nh c\u1ee7a BloC, stream \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng \u0111\u1ec3 truy\u1ec1n t\u1ea3i c\u00e1c state t\u1eeb BloC \u0111\u1ebfn c\u00e1c widget.<\/span><\/p>\n<p><b>Vai tr\u00f2:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Truy\u1ec1n t\u1ea3i d\u1eef li\u1ec7u: Stream cho ph\u00e9p truy\u1ec1n t\u1ea3i d\u1eef li\u1ec7u m\u1ed9t c\u00e1ch hi\u1ec7u qu\u1ea3 v\u00e0 ph\u1ea3n \u1ee9ng.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">C\u1eadp nh\u1eadt UI: C\u00e1c widget l\u1eafng nghe stream c\u1ee7a BloC \u0111\u1ec3 nh\u1eadn c\u00e1c state m\u1edbi v\u00e0 c\u1eadp nh\u1eadt giao di\u1ec7n.<\/span><\/li>\n<\/ul>\n<p><b>V\u00ed d\u1ee5:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">\u1ee8ng d\u1ee5ng chat: Stream \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng \u0111\u1ec3 truy\u1ec1n t\u1ea3i c\u00e1c tin nh\u1eafn m\u1edbi t\u1eeb server \u0111\u1ebfn \u1ee9ng d\u1ee5ng, gi\u00fap cho giao di\u1ec7n chat lu\u00f4n \u0111\u01b0\u1ee3c c\u1eadp nh\u1eadt.<\/span><\/li>\n<\/ul>\n<blockquote><p><em>\u0110\u1ecdc th\u00eam:<\/em><\/p>\n<ul>\n<li><a href=\"https:\/\/itviec.com\/blog\/flutter-roadmap-lo-trinh-hoc-flutter\/\" target=\"_blank\" rel=\"noopener\"><strong><em>Flutter roadmap: L\u1ed9 tr\u00ecnh h\u1ecdc Flutter to\u00e0n di\u1ec7n A-Z<\/em><\/strong><\/a><\/li>\n<li><em><a href=\"https:\/\/itviec.com\/blog\/tai-lieu-hoc-flutter\/\" target=\"_blank\" rel=\"noopener\"><strong>H\u1ecdc Flutter to\u00e0n di\u1ec7n v\u1edbi 50+ t\u00e0i li\u1ec7u Flutter m\u1edbi nh\u1ea5t<\/strong><\/a><\/em><\/li>\n<\/ul>\n<\/blockquote>\n<h2><span class=\"ez-toc-section\" id=\"So_do_hoat_dong_cua_BloC_Flutter\"><\/span><b>S\u01a1 \u0111\u1ed3 ho\u1ea1t \u0111\u1ed9ng c\u1ee7a BloC Flutter<\/b><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<pre>flowchart LR\r\n    A(UI) --&gt; B(Event)\r\n    B --&gt; C(Bloc)\r\n    C --&gt; D(State)\r\n    D --&gt; A\r\n    subgraph Bloc\r\n        C --&gt; E(Stream)\r\n    end<\/pre>\n<p><b>Gi\u1ea3i th\u00edch:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Ng\u01b0\u1eddi d\u00f9ng t\u01b0\u01a1ng t\u00e1c v\u1edbi giao di\u1ec7n (UI), t\u1ea1o ra c\u00e1c event.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Event \u0111\u01b0\u1ee3c g\u1eedi \u0111\u1ebfn BloC.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">BloC x\u1eed l\u00fd event v\u00e0 t\u1ea1o ra m\u1ed9t state m\u1edbi.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">State m\u1edbi \u0111\u01b0\u1ee3c ph\u00e1t ra qua stream.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">C\u00e1c widget l\u1eafng nghe stream v\u00e0 c\u1eadp nh\u1eadt giao di\u1ec7n d\u1ef1a tr\u00ean state m\u1edbi.<\/span><\/li>\n<\/ul>\n<p><b>T\u00f3m t\u1eaft<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Event: M\u00f4 t\u1ea3 m\u1ed9t h\u00e0nh \u0111\u1ed9ng ho\u1eb7c s\u1ef1 ki\u1ec7n.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">State: M\u00f4 t\u1ea3 tr\u1ea1ng th\u00e1i hi\u1ec7n t\u1ea1i c\u1ee7a \u1ee9ng d\u1ee5ng.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">BloC: X\u1eed l\u00fd logic nghi\u1ec7p v\u1ee5 v\u00e0 qu\u1ea3n l\u00fd state.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Stream: Truy\u1ec1n t\u1ea3i state t\u1eeb BloC \u0111\u1ebfn widget.<\/span><\/li>\n<\/ul>\n<p><b>C\u00e1c kh\u00e1i ni\u1ec7m n\u00e2ng cao:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Middleware: Cho ph\u00e9p ch\u1eb7n, s\u1eeda \u0111\u1ed5i ho\u1eb7c th\u1ef1c hi\u1ec7n c\u00e1c t\u00e1c v\u1ee5 ph\u1ee5 tr\u01b0\u1edbc khi event \u0111\u01b0\u1ee3c x\u1eed l\u00fd.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">BloCProvider: Cung c\u1ea5p m\u1ed9t c\u00e1ch \u0111\u1ec3 cung c\u1ea5p BloC cho c\u00e1c widget con.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Cubit: M\u1ed9t phi\u00ean b\u1ea3n \u0111\u01a1n gi\u1ea3n h\u00f3a c\u1ee7a BloC, ph\u00f9 h\u1ee3p v\u1edbi c\u00e1c tr\u01b0\u1eddng h\u1ee3p s\u1eed d\u1ee5ng \u0111\u01a1n gi\u1ea3n.<\/span><\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Uu_diem_cua_BloC_Pattern\"><\/span><strong>\u01afu \u0111i\u1ec3m c\u1ee7a BloC Pattern<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul>\n<li><b>T\u00e1ch bi\u1ec7t r\u00f5 r\u00e0ng<\/b><span style=\"font-weight: 400;\">: T\u00e1ch bi\u1ec7t r\u00f5 r\u00e0ng gi\u1eefa logic nghi\u1ec7p v\u1ee5 v\u00e0 UI.<\/span><\/li>\n<li><b>D\u1ec5 ki\u1ec3m th\u1eed<\/b><span style=\"font-weight: 400;\">: Logic nghi\u1ec7p v\u1ee5 c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c ki\u1ec3m th\u1eed ri\u00eang bi\u1ec7t v\u1edbi UI.<\/span><\/li>\n<li><b>Kh\u1ea3 n\u0103ng m\u1edf r\u1ed9ng<\/b><span style=\"font-weight: 400;\">: D\u1ec5 m\u1edf r\u1ed9ng \u1ee9ng d\u1ee5ng b\u1eb1ng c\u00e1ch th\u00eam t\u00ednh n\u0103ng m\u1edbi m\u00e0 kh\u00f4ng \u1ea3nh h\u01b0\u1edfng \u0111\u1ebfn ch\u1ee9c n\u0103ng hi\u1ec7n t\u1ea1i.<\/span><\/li>\n<li><b>D\u1ec5 b\u1ea3o tr\u00ec<\/b><span style=\"font-weight: 400;\">: D\u1ec5 b\u1ea3o tr\u00ec do thay \u0111\u1ed5i trong logic nghi\u1ec7p v\u1ee5 kh\u00f4ng \u1ea3nh h\u01b0\u1edfng \u0111\u1ebfn UI v\u00e0 ng\u01b0\u1ee3c l\u1ea1i.<\/span><\/li>\n<\/ul>\n<p><b>T\u1ed5ng k\u1ebft:<\/b><span style=\"font-weight: 400;\"> Hi\u1ec3u r\u00f5 v\u1ec1 State, BloC v\u00e0 Stream l\u00e0 n\u1ec1n t\u1ea3ng \u0111\u1ec3 b\u1ea1n c\u00f3 th\u1ec3 \u00e1p d\u1ee5ng ki\u1ebfn tr\u00fac BloC v\u00e0o c\u00e1c d\u1ef1 \u00e1n Flutter c\u1ee7a m\u00ecnh. B\u1eb1ng c\u00e1ch t\u00e1ch bi\u1ec7t logic nghi\u1ec7p v\u1ee5 kh\u1ecfi giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng, b\u1ea1n s\u1ebd x\u00e2y d\u1ef1ng \u0111\u01b0\u1ee3c c\u00e1c \u1ee9ng d\u1ee5ng Flutter c\u00f3 c\u1ea5u tr\u00fac t\u1ed1t, d\u1ec5 b\u1ea3o tr\u00ec v\u00e0 m\u1edf r\u1ed9ng.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">BloC pattern l\u00e0 m\u1ed9t c\u00e1ch m\u1ea1nh m\u1ebd \u0111\u1ec3 qu\u1ea3n l\u00fd tr\u1ea1ng th\u00e1i trong \u1ee9ng d\u1ee5ng Flutter. B\u1eb1ng c\u00e1ch t\u00e1ch bi\u1ec7t logic nghi\u1ec7p v\u1ee5 kh\u1ecfi UI, n\u00f3 gi\u00fap \u1ee9ng d\u1ee5ng c\u1ee7a b\u1ea1n d\u1ec5 b\u1ea3o tr\u00ec, m\u1edf r\u1ed9ng v\u00e0 ki\u1ec3m th\u1eed h\u01a1n. Hi\u1ec3u v\u00e0 th\u1ef1c hi\u1ec7n BloC pattern c\u00f3 th\u1ec3 c\u1ea3i thi\u1ec7n quy tr\u00ecnh ph\u00e1t tri\u1ec3n v\u00e0 d\u1eabn \u0111\u1ebfn m\u00e3 s\u1ea1ch h\u01a1n, hi\u1ec7u qu\u1ea3 h\u01a1n.<\/span><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Cach_trien_khai_BloC_Flutter\"><\/span><strong>C\u00e1ch tri\u1ec3n khai BloC Flutter<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><b>K\u1ebf th\u1eeba t\u1eeb l\u1edbp BloC:<\/b><span style=\"font-weight: 400;\"> T\u1ea1o m\u1ed9t l\u1edbp m\u1edbi k\u1ebf th\u1eeba t\u1eeb l\u1edbp <\/span><span style=\"font-weight: 400;\">BloC<\/span><span style=\"font-weight: 400;\"> trong th\u01b0 vi\u1ec7n <\/span><span style=\"font-weight: 400;\">flutter_BloC<\/span><span style=\"font-weight: 400;\">. L\u1edbp n\u00e0y s\u1ebd \u0111\u1ecbnh ngh\u0129a c\u00e1c event, state v\u00e0 logic x\u1eed l\u00fd c\u1ee7a BloC.<\/span><\/p>\n<p><b>\u0110\u1ecbnh ngh\u0129a event v\u00e0 state:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Event:<\/b><span style=\"font-weight: 400;\"> T\u1ea1o c\u00e1c l\u1edbp con c\u1ee7a <\/span><span style=\"font-weight: 400;\">Equatable<\/span><span style=\"font-weight: 400;\"> \u0111\u1ec3 \u0111\u1ea1i di\u1ec7n cho c\u00e1c s\u1ef1 ki\u1ec7n c\u00f3 th\u1ec3 x\u1ea3y ra.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>State:<\/b><span style=\"font-weight: 400;\"> T\u1ea1o c\u00e1c l\u1edbp con c\u1ee7a <\/span><span style=\"font-weight: 400;\">Equatable<\/span><span style=\"font-weight: 400;\"> \u0111\u1ec3 \u0111\u1ea1i di\u1ec7n cho c\u00e1c tr\u1ea1ng th\u00e1i kh\u00e1c nhau c\u1ee7a \u1ee9ng d\u1ee5ng.<\/span><\/li>\n<\/ul>\n<p><b>Implement <\/b><b>mapEventToState<\/b><b>:<\/b><span style=\"font-weight: 400;\"> Ph\u01b0\u01a1ng th\u1ee9c n\u00e0y nh\u1eadn m\u1ed9t event v\u00e0 tr\u1ea3 v\u1ec1 m\u1ed9t stream c\u1ee7a state m\u1edbi. \u0110\u00e2y l\u00e0 n\u01a1i b\u1ea1n th\u1ef1c hi\u1ec7n logic x\u1eed l\u00fd event v\u00e0 c\u1eadp nh\u1eadt state.<\/span><\/p>\n<pre>import 'package:flutter_bloc\/flutter_bloc.dart';\r\nimport 'package:equatable\/equatable.dart';\r\n\r\npart 'counter_event.dart';\r\npart 'counter_state.dart';\r\n\r\nclass CounterBloc\r\n  extends Bloc&lt;Counter Event, CounterState&gt; {\r\n    CounterBloc(): super(const CounterState())\r\n  {\r\n      on&lt;IncrementEvent&gt;((event, emit) =&gt; emit (state.increment()));\r\n      on&lt;DecrementEvent&gt;((event, emit) =&gt; emit (state.decrement()));\r\n  }\r\n}<\/pre>\n<h3><strong>T\u1ea1o BloC class<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">\u0110\u1ec3 t\u1ea1o m\u1ed9t l\u1edbp BloC trong Flutter, b\u1ea1n c\u1ea7n l\u00e0m theo c\u00e1c b\u01b0\u1edbc sau \u0111\u00e2y:<\/span><\/p>\n<h4><strong>B\u01b0\u1edbc 1: \u0110\u1ecbnh ngh\u0129a c\u00e1c s\u1ef1 ki\u1ec7n (Event)<\/strong><\/h4>\n<p><span style=\"font-weight: 400;\">S\u1ef1 ki\u1ec7n l\u00e0 c\u00e1c h\u00e0nh \u0111\u1ed9ng m\u00e0 ng\u01b0\u1eddi d\u00f9ng th\u1ef1c hi\u1ec7n ho\u1eb7c l\u00e0 c\u00e1c s\u1ef1 ki\u1ec7n m\u00e0 \u1ee9ng d\u1ee5ng c\u1ea7n x\u1eed l\u00fd. B\u1ea1n c\u1ea7n t\u1ea1o c\u00e1c l\u1edbp s\u1ef1 ki\u1ec7n \u0111\u1ec3 bi\u1ec3u di\u1ec5n nh\u1eefng h\u00e0nh \u0111\u1ed9ng n\u00e0y.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">V\u00ed d\u1ee5: Trong m\u1ed9t \u1ee9ng d\u1ee5ng \u0111\u1ebfm, b\u1ea1n c\u00f3 th\u1ec3 c\u00f3 c\u00e1c s\u1ef1 ki\u1ec7n Increment v\u00e0 Decrement.<\/span><\/p>\n<pre>\/\/ counter_event.dart\r\nabstract class CounterEvent {}\r\n\r\nclass IncrementEvent extends CounterEvent {}\r\nclass DecrementEvent extends CounterEvent {}<\/pre>\n<h4><strong>B\u01b0\u1edbc 2: \u0110\u1ecbnh ngh\u0129a c\u00e1c tr\u1ea1ng th\u00e1i (State)<\/strong><\/h4>\n<p><span style=\"font-weight: 400;\">Tr\u1ea1ng th\u00e1i l\u00e0 d\u1eef li\u1ec7u hi\u1ec7n t\u1ea1i c\u1ee7a \u1ee9ng d\u1ee5ng. B\u1ea1n c\u1ea7n t\u1ea1o c\u00e1c l\u1edbp tr\u1ea1ng th\u00e1i \u0111\u1ec3 bi\u1ec3u di\u1ec5n nh\u1eefng d\u1eef li\u1ec7u n\u00e0y.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">V\u00ed d\u1ee5: Trong \u1ee9ng d\u1ee5ng \u0111\u1ebfm, tr\u1ea1ng th\u00e1i l\u00e0 gi\u00e1 tr\u1ecb c\u1ee7a b\u1ed9 \u0111\u1ebfm.<\/span><\/p>\n<pre>\/\/ counter_state.dart\r\nclass CounterState {\r\n\u00a0 final int counterValue;\r\n\u00a0 CounterState(this.counterValue);\r\n}<\/pre>\n<h4><strong>B\u01b0\u1edbc 3: T\u1ea1o l\u1edbp BloC<\/strong><\/h4>\n<p><span style=\"font-weight: 400;\">L\u1edbp BloC s\u1ebd ch\u1ee9a logic nghi\u1ec7p v\u1ee5 c\u1ee7a \u1ee9ng d\u1ee5ng. N\u00f3 s\u1ebd l\u1eafng nghe c\u00e1c s\u1ef1 ki\u1ec7n v\u00e0 ph\u00e1t ra c\u00e1c tr\u1ea1ng th\u00e1i m\u1edbi d\u1ef1a tr\u00ean c\u00e1c s\u1ef1 ki\u1ec7n n\u00e0y.<\/span><\/p>\n<pre>\/\/ counter_BloC.dart\r\nimport 'dart:async';\r\nimport 'counter_event.dart';\r\nimport 'counter_state.dart';\r\n\r\nclass CounterBloC {\r\n\u00a0 final _counterStateController = StreamController&lt;CounterState&gt;();\r\n\u00a0 Stream&lt;CounterState&gt; get counter =&gt; _counterStateController.stream;\r\n\r\n\u00a0 final _counterEventController = StreamController&lt;CounterEvent&gt;();\r\n\u00a0 Sink&lt;CounterEvent&gt; get counterEventSink =&gt; _counterEventController.sink;\r\n\r\n\u00a0 int _counterValue = 0;\r\n\r\n\u00a0 CounterBloC() {\r\n\u00a0 \u00a0 _counterEventController.stream.listen(_mapEventToState);\r\n\u00a0 }\r\n\r\n\u00a0 void _mapEventToState(CounterEvent event) {\r\n\u00a0 \u00a0 if (event is IncrementEvent) {\r\n\u00a0 \u00a0 \u00a0 _counterValue++;\r\n\u00a0 \u00a0 } else if (event is DecrementEvent) {\r\n\u00a0 \u00a0 \u00a0 _counterValue--;\r\n\u00a0 \u00a0 }\r\n\u00a0 \u00a0 _counterStateController.add(CounterState(_counterValue));\r\n\u00a0 }\r\n\r\n\u00a0 void dispose() {\r\n\u00a0 \u00a0 _counterStateController.close();\r\n\u00a0 \u00a0 _counterEventController.close();\r\n\u00a0 }\r\n}<\/pre>\n<h4><strong>B\u01b0\u1edbc 4: T\u00edch h\u1ee3p BloC v\u1edbi UI<\/strong><\/h4>\n<p><span style=\"font-weight: 400;\">S\u1eed d\u1ee5ng StreamBuilder \u0111\u1ec3 l\u1eafng nghe c\u00e1c thay \u0111\u1ed5i tr\u1ea1ng th\u00e1i t\u1eeb BloC v\u00e0 c\u1eadp nh\u1eadt UI t\u01b0\u01a1ng \u1ee9ng.<\/span><\/p>\n<pre>\/\/ main.dart\r\nimport 'package:flutter\/material.dart';\r\nimport 'counter_BloC.dart';\r\nimport 'counter_event.dart';\r\nimport 'counter_state.dart';\r\n\r\nvoid main() =&gt; runApp(MyApp());\r\n\r\nclass MyApp extends StatelessWidget {\r\n\u00a0 @override\r\n\u00a0 Widget build(BuildContext context) {\r\n\u00a0 \u00a0 return MaterialApp(\r\n\u00a0 \u00a0 \u00a0 home: CounterPage(),\r\n\u00a0 \u00a0 );\r\n\u00a0 }\r\n}\r\n\r\nclass CounterPage extends StatelessWidget {\r\n\u00a0 final CounterBloC _BloC = CounterBloC();\r\n\r\n\u00a0 @override\r\n\u00a0 Widget build(BuildContext context) {\r\n\u00a0 \u00a0 return Scaffold(\r\n\u00a0 \u00a0 \u00a0 appBar: AppBar(title: Text('BloC Pattern')),\r\n\u00a0 \u00a0 \u00a0 body: StreamBuilder&lt;CounterState&gt;(\r\n\u00a0 \u00a0 \u00a0 \u00a0 stream: _BloC.counter,\r\n\u00a0 \u00a0 \u00a0 \u00a0 initialData: CounterState(0),\r\n\u00a0 \u00a0 \u00a0 \u00a0 builder: (context, snapshot) {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return Center(\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 child: Text(\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 'Counter: ${snapshot.data.counterValue}',\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 style: TextStyle(fontSize: 24),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 );\r\n\u00a0 \u00a0 \u00a0 \u00a0 },\r\n\u00a0 \u00a0 \u00a0 ),\r\n\u00a0 \u00a0 \u00a0 floatingActionButton: Column(\r\n\u00a0 \u00a0 \u00a0 \u00a0 mainAxisAlignment: MainAxisAlignment.end,\r\n\u00a0 \u00a0 \u00a0 \u00a0 children: &lt;Widget&gt;[\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 FloatingActionButton(\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 onPressed: () =&gt; _BloC.counterEventSink.add(IncrementEvent()),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 child: Icon(Icons.add),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 SizedBox(height: 10),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 FloatingActionButton(\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 onPressed: () =&gt; _BloC.counterEventSink.add(DecrementEvent()),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 child: Icon(Icons.remove),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ),\r\n\u00a0 \u00a0 \u00a0 \u00a0 ],\r\n\u00a0 \u00a0 \u00a0 ),\r\n\u00a0 \u00a0 );\r\n\u00a0 }\r\n}<\/pre>\n<h4><strong>B\u01b0\u1edbc 5: D\u1ecdn d\u1eb9p t\u00e0i nguy\u00ean<\/strong><\/h4>\n<p><span style=\"font-weight: 400;\">\u0110\u1eebng qu\u00ean g\u1ecdi ph\u01b0\u01a1ng th\u1ee9c dispose c\u1ee7a BloC khi b\u1ea1n kh\u00f4ng c\u00f2n s\u1eed d\u1ee5ng n\u00f3 \u0111\u1ec3 gi\u1ea3i ph\u00f3ng t\u00e0i nguy\u00ean.<\/span><\/p>\n<pre>@override\r\nvoid dispose() {\r\n\u00a0 _BloC.dispose();\r\n\u00a0 super.dispose();\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">T\u00f3m t\u1eaft \u0111\u1ec3 t\u1ea1o m\u1ed9t class BloC, ch\u00fang ta c\u1ea7n ph\u1ea3i:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">\u0110\u1ecbnh ngh\u0129a c\u00e1c s\u1ef1 ki\u1ec7n v\u00e0 tr\u1ea1ng th\u00e1i: T\u1ea1o c\u00e1c l\u1edbp \u0111\u1ec3 bi\u1ec3u di\u1ec5n s\u1ef1 ki\u1ec7n v\u00e0 tr\u1ea1ng th\u00e1i c\u1ee7a \u1ee9ng d\u1ee5ng.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">T\u1ea1o l\u1edbp BloC: L\u1edbp n\u00e0y ch\u1ee9a logic nghi\u1ec7p v\u1ee5, l\u1eafng nghe s\u1ef1 ki\u1ec7n v\u00e0 ph\u00e1t ra tr\u1ea1ng th\u00e1i.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">T\u00edch h\u1ee3p BloC v\u1edbi UI: S\u1eed d\u1ee5ng StreamBuilder \u0111\u1ec3 l\u1eafng nghe c\u00e1c thay \u0111\u1ed5i tr\u1ea1ng th\u00e1i t\u1eeb BloC v\u00e0 c\u1eadp nh\u1eadt UI.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">D\u1ecdn d\u1eb9p t\u00e0i nguy\u00ean: \u0110\u1ea3m b\u1ea3o gi\u1ea3i ph\u00f3ng t\u00e0i nguy\u00ean khi kh\u00f4ng c\u00f2n s\u1eed d\u1ee5ng BloC.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Nh\u01b0 v\u1eady, b\u1ea1n \u0111\u00e3 bi\u1ebft c\u00e1ch t\u1ea1o m\u1ed9t l\u1edbp BloC trong Flutter v\u00e0 t\u00edch h\u1ee3p n\u00f3 v\u00e0o \u1ee9ng d\u1ee5ng c\u1ee7a m\u00ecnh.<\/span><\/p>\n<h3><strong>X\u1eed l\u00fd event trong BloC class<\/strong><\/h3>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Nh\u1eadn event:<\/b><span style=\"font-weight: 400;\"> Trong ph\u01b0\u01a1ng th\u1ee9c <\/span><span style=\"font-weight: 400;\">mapEventToState<\/span><span style=\"font-weight: 400;\">, BloC nh\u1eadn \u0111\u01b0\u1ee3c event \u0111\u01b0\u1ee3c g\u1eedi t\u1eeb UI.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Th\u1ef1c hi\u1ec7n logic:<\/b><span style=\"font-weight: 400;\"> D\u1ef1a tr\u00ean lo\u1ea1i event, BloC s\u1ebd th\u1ef1c hi\u1ec7n c\u00e1c ph\u00e9p t\u00ednh, g\u1ecdi API ho\u1eb7c c\u00e1c t\u00e1c v\u1ee5 kh\u00e1c \u0111\u1ec3 c\u1eadp nh\u1eadt state.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Tr\u00e1nh thay \u0111\u1ed5i state tr\u1ef1c ti\u1ebfp:<\/b><span style=\"font-weight: 400;\"> Lu\u00f4n s\u1eed d\u1ee5ng h\u00e0m <\/span><span style=\"font-weight: 400;\">emit<\/span><span style=\"font-weight: 400;\"> \u0111\u1ec3 ph\u00e1t ra state m\u1edbi.<\/span><\/li>\n<\/ul>\n<h3><strong>C\u1eadp nh\u1eadt state trong BloC class<\/strong><\/h3>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>S\u1eed d\u1ee5ng h\u00e0m <\/b><b>emit<\/b><b>:<\/b><span style=\"font-weight: 400;\"> Khi c\u1ea7n c\u1eadp nh\u1eadt state, g\u1ecdi h\u00e0m <\/span><span style=\"font-weight: 400;\">emit<\/span><span style=\"font-weight: 400;\"> v\u1edbi state m\u1edbi.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>T\u1ea1o state m\u1edbi:<\/b><span style=\"font-weight: 400;\"> T\u1ea1o m\u1ed9t \u0111\u1ed1i t\u01b0\u1ee3ng state m\u1edbi d\u1ef1a tr\u00ean state hi\u1ec7n t\u1ea1i v\u00e0 c\u00e1c thay \u0111\u1ed5i c\u1ea7n th\u1ef1c hi\u1ec7n.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Ph\u00e1t ra state m\u1edbi:<\/b><span style=\"font-weight: 400;\"> H\u00e0m <\/span><span style=\"font-weight: 400;\">emit<\/span><span style=\"font-weight: 400;\"> s\u1ebd t\u1ef1 \u0111\u1ed9ng ph\u00e1t ra state m\u1edbi qua stream.<\/span><\/li>\n<\/ul>\n<h3><strong>Truy c\u1eadp BloC t\u1eeb widget<\/strong><\/h3>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>S\u1eed d\u1ee5ng <\/b><b>BloCProvider<\/b><b>:<\/b><span style=\"font-weight: 400;\"> Wrap widget cha c\u1ee7a widget c\u1ea7n truy c\u1eadp BloC b\u1eb1ng <\/span><span style=\"font-weight: 400;\">BloCProvider<\/span><span style=\"font-weight: 400;\">.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Truy c\u1eadp BloC:<\/b><span style=\"font-weight: 400;\"> Trong widget con, s\u1eed d\u1ee5ng <\/span><span style=\"font-weight: 400;\">context.read&lt;YourBloC&gt;()<\/span><span style=\"font-weight: 400;\"> ho\u1eb7c <\/span><span style=\"font-weight: 400;\">context.watch&lt;YourBloC&gt;()<\/span><span style=\"font-weight: 400;\"> \u0111\u1ec3 truy c\u1eadp v\u00e0o instance c\u1ee7a BloC.<\/span><\/li>\n<\/ul>\n<pre>class MyWidget extends StatelessWidget {\r\n  @override\r\n  Widget build (BuildContext context) {\r\n    final counterBloc = context.read&lt;CounterBloc&gt;();\r\n    return ElevatedButton(\r\n      onPressed: () {\r\n        counterBloc.add(IncrementEvent());\r\n      },\r\n      child: Text('Increment'),\r\n    );\r\n  }\r\n}<\/pre>\n<h3><strong>S\u1eed d\u1ee5ng BloCProvider \u0111\u1ec3 cung c\u1ea5p BloC cho widget con<\/strong><\/h3>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Wrap widget cha:<\/b><span style=\"font-weight: 400;\"> S\u1eed d\u1ee5ng <\/span><span style=\"font-weight: 400;\">BloCProvider<\/span><span style=\"font-weight: 400;\"> \u0111\u1ec3 wrap widget cha c\u1ee7a t\u1ea5t c\u1ea3 c\u00e1c widget c\u1ea7n truy c\u1eadp BloC.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Truy\u1ec1n BloC:<\/b><span style=\"font-weight: 400;\"> Truy\u1ec1n instance c\u1ee7a BloC v\u00e0o <\/span><span style=\"font-weight: 400;\">create: (context) =&gt; YourBloC()<\/span><span style=\"font-weight: 400;\"> trong <\/span><span style=\"font-weight: 400;\">BloCProvider<\/span><span style=\"font-weight: 400;\">.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Truy c\u1eadp BloC:<\/b><span style=\"font-weight: 400;\"> C\u00e1c widget con c\u00f3 th\u1ec3 truy c\u1eadp BloC b\u1eb1ng c\u00e1ch s\u1eed d\u1ee5ng <\/span><span style=\"font-weight: 400;\">context.read<\/span><span style=\"font-weight: 400;\"> ho\u1eb7c <\/span><span style=\"font-weight: 400;\">context.watch<\/span><span style=\"font-weight: 400;\">.<\/span><\/li>\n<\/ul>\n<pre>class MyApp extends StatelessWidget {\r\n  @override\r\n  Widget build(BuildContext context) {\r\n    return MaterialApp(\r\n      home: BlocProvider(\r\n        create: (context) =&gt; Counter Bloc(),\r\n\r\n        child: MyHomePage(),\r\n      ),\r\n    );\r\n  }\r\n}<\/pre>\n<p><b>Gi\u1ea3i th\u00edch chi ti\u1ebft h\u01a1n:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Equatable<\/b><span style=\"font-weight: 400;\">: S\u1eed d\u1ee5ng \u0111\u1ec3 so s\u00e1nh c\u00e1c \u0111\u1ed1i t\u01b0\u1ee3ng state v\u00e0 event m\u1ed9t c\u00e1ch hi\u1ec7u qu\u1ea3.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>mapEventToState<\/b><span style=\"font-weight: 400;\">: \u0110\u00e2y l\u00e0 tr\u00e1i tim c\u1ee7a BloC, n\u01a1i logic x\u1eed l\u00fd event di\u1ec5n ra.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>emit<\/b><span style=\"font-weight: 400;\">: H\u00e0m n\u00e0y \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng \u0111\u1ec3 ph\u00e1t ra state m\u1edbi. Khi state thay \u0111\u1ed5i, c\u00e1c widget l\u1eafng nghe s\u1ebd t\u1ef1 \u0111\u1ed9ng rebuild.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>context.read<\/b><span style=\"font-weight: 400;\">: \u0110\u01b0\u1ee3c s\u1eed d\u1ee5ng \u0111\u1ec3 \u0111\u1ecdc BloC m\u00e0 kh\u00f4ng g\u00e2y ra rebuild.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>context.watch<\/b><span style=\"font-weight: 400;\">: \u0110\u01b0\u1ee3c s\u1eed d\u1ee5ng \u0111\u1ec3 \u0111\u1ecdc BloC v\u00e0 g\u00e2y ra rebuild khi state thay \u0111\u1ed5i.<\/span><\/li>\n<\/ul>\n<p><b>V\u00ed d\u1ee5 c\u1ee5 th\u1ec3:<\/b><\/p>\n<p><b>Gi\u1ea3 s\u1eed ch\u00fang ta c\u00f3 m\u1ed9t \u1ee9ng d\u1ee5ng \u0111\u1ebfm s\u1ed1.<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Event<\/b><span style=\"font-weight: 400;\">: IncrementEvent, DecrementEvent.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>State<\/b><span style=\"font-weight: 400;\">: CounterState (ch\u1ee9a gi\u00e1 tr\u1ecb counter).<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>BloC<\/b><span style=\"font-weight: 400;\">: CounterBloC x\u1eed l\u00fd c\u00e1c event t\u0103ng gi\u1ea3m gi\u00e1 tr\u1ecb counter v\u00e0 c\u1eadp nh\u1eadt state.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Widget<\/b><span style=\"font-weight: 400;\">: Hi\u1ec3n th\u1ecb gi\u00e1 tr\u1ecb counter v\u00e0 c\u00f3 hai n\u00fat t\u0103ng gi\u1ea3m.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Khi ng\u01b0\u1eddi d\u00f9ng nh\u1ea5n n\u00fat t\u0103ng, m\u1ed9t <\/span><b>IncrementEvent<\/b><span style=\"font-weight: 400;\"> \u0111\u01b0\u1ee3c g\u1eedi \u0111\u1ebfn <\/span><b>CounterBloC<\/b><span style=\"font-weight: 400;\">. BloC t\u0103ng gi\u00e1 tr\u1ecb counter v\u00e0 ph\u00e1t ra state m\u1edbi. Widget l\u1eafng nghe <\/span><b>state<\/b><span style=\"font-weight: 400;\"> n\u00e0y v\u00e0 c\u1eadp nh\u1eadt giao di\u1ec7n \u0111\u1ec3 hi\u1ec3n th\u1ecb gi\u00e1 tr\u1ecb counter m\u1edbi.<\/span><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Vi_du_ung_dung_thuc_te_cua_BloC_Flutter\"><\/span><strong>V\u00ed d\u1ee5 \u1ee9ng d\u1ee5ng th\u1ef1c t\u1ebf c\u1ee7a BloC Flutter<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><span style=\"font-weight: 400;\">\u0110\u1ec3 hi\u1ec3u r\u00f5 h\u01a1n v\u1ec1 c\u00e1ch s\u1eed d\u1ee5ng BloC trong th\u1ef1c t\u1ebf, ch\u00fang ta s\u1ebd x\u00e2y d\u1ef1ng m\u1ed9t \u1ee9ng d\u1ee5ng Flutter \u0111\u01a1n gi\u1ea3n: m\u1ed9t counter. \u1ee8ng d\u1ee5ng n\u00e0y s\u1ebd c\u00f3 hai n\u00fat: &#8220;T\u0103ng&#8221; v\u00e0 &#8220;Gi\u1ea3m&#8221;, v\u00e0 m\u1ed9t text hi\u1ec3n th\u1ecb gi\u00e1 tr\u1ecb hi\u1ec7n t\u1ea1i c\u1ee7a counter.<\/span><\/p>\n<h3><b>C\u1ea5u tr\u00fac d\u1ef1 \u00e1n<\/b><\/h3>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>event:<\/b> <span style=\"font-weight: 400;\">IncrementEvent<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">DecrementEvent<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>state:<\/b> <span style=\"font-weight: 400;\">CounterState<\/span><span style=\"font-weight: 400;\"> (ch\u1ee9a gi\u00e1 tr\u1ecb hi\u1ec7n t\u1ea1i c\u1ee7a counter)<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>BloC:<\/b> <span style=\"font-weight: 400;\">CounterBloC<\/span><span style=\"font-weight: 400;\"> (x\u1eed l\u00fd c\u00e1c event v\u00e0 c\u1eadp nh\u1eadt state)<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>widget:<\/b> <span style=\"font-weight: 400;\">CounterPage<\/span><span style=\"font-weight: 400;\"> (hi\u1ec3n th\u1ecb giao di\u1ec7n v\u00e0 t\u01b0\u01a1ng t\u00e1c v\u1edbi BloC)<\/span><\/li>\n<\/ul>\n<h3><b>M\u00e3 code chi ti\u1ebft<\/b><\/h3>\n<p><b>Thi\u1ebft l\u1eadp c\u01a1 b\u1ea3n<\/b><\/p>\n<pre>dependencies:\r\n  flutter:\r\n    sdk: flutter\r\n  flutter_bloc: ^8.0.0<\/pre>\n<p><span style=\"font-weight: 400;\">Tr\u01b0\u1edbc h\u1ebft, ch\u00fang ta c\u1ea7n c\u00e0i \u0111\u1eb7t th\u01b0 vi\u1ec7n <\/span><span style=\"font-weight: 400;\">flutter_BloC<\/span><span style=\"font-weight: 400;\"> trong d\u1ef1 \u00e1n Flutter:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Sau \u0111\u00f3, ch\u00fang ta s\u1ebd \u0111\u1ecbnh ngh\u0129a c\u00e1c ph\u1ea7n ch\u00ednh c\u1ee7a m\u00f4 h\u00ecnh BloC: Event, State, v\u00e0 BloC.<\/span><\/p>\n<p><b>\u0110\u1ecbnh ngh\u0129a c\u00e1c Events<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Event trong \u1ee9ng d\u1ee5ng Counter n\u00e0y s\u1ebd bao g\u1ed3m hai lo\u1ea1i: Increment v\u00e0 Decrement.<\/span><\/p>\n<pre>\/\/ counter_event.dart\r\nabstract class CounterEvent {}\r\n\r\nclass IncrementEvent extends CounterEvent {}\r\n\r\nclass DecrementEvent extends CounterEvent {}<\/pre>\n<p><b>\u0110\u1ecbnh ngh\u0129a State<\/b><\/p>\n<p><span style=\"font-weight: 400;\">State s\u1ebd bi\u1ec3u di\u1ec5n tr\u1ea1ng th\u00e1i hi\u1ec7n t\u1ea1i c\u1ee7a b\u1ed9 \u0111\u1ebfm.<\/span><\/p>\n<pre>\/\/ counter_state.dart\r\nclass CounterState {\r\n  final int counterValue;\r\n\r\n  CounterState({required this.counterValue});\r\n}<\/pre>\n<p><b>\u0110\u1ecbnh ngh\u0129a BloC<\/b><\/p>\n<p><span style=\"font-weight: 400;\">BloC s\u1ebd qu\u1ea3n l\u00fd logic x\u1eed l\u00fd cho c\u00e1c s\u1ef1 ki\u1ec7n v\u00e0 c\u1eadp nh\u1eadt state.<\/span><\/p>\n<pre>\/\/ counter_bloc.dart\r\nimport 'package:flutter_bloc\/flutter_bloc.dart';\r\nimport 'counter_event.dart';\r\nimport 'counter_state.dart';\r\n\r\nclass CounterBloc extends Bloc&lt;CounterEvent, CounterState&gt; {\r\n  CounterBloc(): super(CounterState (counterValue: 0)) {\r\n    on&lt;IncrementEvent&gt;((event, emit) {\r\n      emit (CounterState (counterValue: state.counterValue + 1));\r\n    });\r\n\r\n    on&lt;DecrementEvent&gt;((event, emit) {\r\n      emit (CounterState(counterValue: state.counterValue - 1));\r\n    });\r\n  }\r\n}<\/pre>\n<h3><b>X\u00e2y d\u1ef1ng giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">S\u1eed d\u1ee5ng <\/span><span style=\"font-weight: 400;\">BloCProvider<\/span><span style=\"font-weight: 400;\"> v\u00e0 <\/span><span style=\"font-weight: 400;\">BloCBuilder<\/span><span style=\"font-weight: 400;\"> \u0111\u1ec3 qu\u1ea3n l\u00fd BloC v\u00e0 hi\u1ec3n th\u1ecb tr\u1ea1ng th\u00e1i hi\u1ec7n t\u1ea1i c\u1ee7a b\u1ed9 \u0111\u1ebfm.<\/span><\/p>\n<pre>\/\/ main.dart\r\nimport 'package:flutter\/material.dart';\r\nimport 'package:flutter_BloC\/flutter_BloC.dart';\r\nimport 'counter_BloC.dart';\r\nimport 'counter_event.dart';\r\nimport 'counter_state.dart';\r\n\r\nvoid main() {\r\n\u00a0 runApp(MyApp());\r\n}\r\n\r\nclass MyApp extends StatelessWidget {\r\n\u00a0 @override\r\n\u00a0 Widget build(BuildContext context) {\r\n\u00a0 \u00a0 return MaterialApp(\r\n\u00a0 \u00a0 \u00a0 home: BloCProvider(\r\n\u00a0 \u00a0 \u00a0 \u00a0 create: (context) =&gt; CounterBloC(),\r\n\u00a0 \u00a0 \u00a0 \u00a0 child: CounterPage(),\r\n\u00a0 \u00a0 \u00a0 ),\r\n\u00a0 \u00a0 );\r\n\u00a0 }\r\n}\r\n\r\nclass CounterPage extends StatelessWidget {\r\n\u00a0 @override\r\n\u00a0 Widget build(BuildContext context) {\r\n\u00a0 \u00a0 final counterBloC = BloCProvider.of&lt;CounterBloC&gt;(context);\r\n\u00a0 \u00a0 return Scaffold(\r\n\u00a0 \u00a0 \u00a0 appBar: AppBar(title: Text('Counter App with BloC')),\r\n\u00a0 \u00a0 \u00a0 body: Center(\r\n\u00a0 \u00a0 \u00a0 \u00a0 child: BloCBuilder&lt;CounterBloC, CounterState&gt;(\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 builder: (context, state) {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 return Text(\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 'Counter Value: ${state.counterValue}',\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 style: TextStyle(fontSize: 24),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 );\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\u00a0 \u00a0 \u00a0 \u00a0 ),\r\n\u00a0 \u00a0 \u00a0 ),\r\n\u00a0 \u00a0 \u00a0 floatingActionButton: Row(\r\n\u00a0 \u00a0 \u00a0 \u00a0 mainAxisAlignment: MainAxisAlignment.end,\r\n\u00a0 \u00a0 \u00a0 \u00a0 children: &lt;Widget&gt;[\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 FloatingActionButton(\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 onPressed: () {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 counterBloC.add(IncrementEvent());\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 child: Icon(Icons.add),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 SizedBox(width: 10),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 FloatingActionButton(\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 onPressed: () {\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 counterBloC.add(DecrementEvent());\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 },\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 child: Icon(Icons.remove),\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ),\r\n\u00a0 \u00a0 \u00a0 \u00a0 ],\r\n\u00a0 \u00a0 \u00a0 ),\r\n\u00a0 \u00a0 );\r\n\u00a0 }\r\n}<\/pre>\n<p><b>Ph\u00e2n t\u00edch c\u00e1ch BloC ho\u1ea1t \u0111\u1ed9ng trong v\u00ed d\u1ee5:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>T\u1ea1o BloC:<\/b><span style=\"font-weight: 400;\"> Ch\u00fang ta t\u1ea1o m\u1ed9t <\/span><span style=\"font-weight: 400;\">CounterBloC<\/span><span style=\"font-weight: 400;\"> \u0111\u1ec3 qu\u1ea3n l\u00fd tr\u1ea1ng th\u00e1i c\u1ee7a counter.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>\u0110\u1ecbnh ngh\u0129a event v\u00e0 state:<\/b> <span style=\"font-weight: 400;\">IncrementEvent<\/span><span style=\"font-weight: 400;\"> v\u00e0 <\/span><span style=\"font-weight: 400;\">DecrementEvent<\/span><span style=\"font-weight: 400;\"> \u0111\u1ea1i di\u1ec7n cho hai h\u00e0nh \u0111\u1ed9ng t\u0103ng v\u00e0 gi\u1ea3m, trong khi <\/span><span style=\"font-weight: 400;\">CounterState<\/span><span style=\"font-weight: 400;\"> l\u01b0u tr\u1eef gi\u00e1 tr\u1ecb hi\u1ec7n t\u1ea1i c\u1ee7a counter.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>X\u1eed l\u00fd event:<\/b><span style=\"font-weight: 400;\"> Trong <\/span><span style=\"font-weight: 400;\">CounterBloC<\/span><span style=\"font-weight: 400;\">, ch\u00fang ta \u0111\u1ecbnh ngh\u0129a c\u00e1ch x\u1eed l\u00fd c\u00e1c event. Khi nh\u1eadn \u0111\u01b0\u1ee3c <\/span><span style=\"font-weight: 400;\">IncrementEvent<\/span><span style=\"font-weight: 400;\">, ch\u00fang ta t\u0103ng gi\u00e1 tr\u1ecb c\u1ee7a state v\u00e0 ph\u00e1t ra state m\u1edbi. T\u01b0\u01a1ng t\u1ef1 v\u1edbi <\/span><span style=\"font-weight: 400;\">DecrementEvent<\/span><span style=\"font-weight: 400;\">.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>C\u1eadp nh\u1eadt giao di\u1ec7n:<\/b><span style=\"font-weight: 400;\"> Trong <\/span><span style=\"font-weight: 400;\">CounterPage<\/span><span style=\"font-weight: 400;\">, ch\u00fang ta s\u1eed d\u1ee5ng <\/span><span style=\"font-weight: 400;\">BloCBuilder<\/span><span style=\"font-weight: 400;\"> \u0111\u1ec3 l\u1eafng nghe c\u00e1c thay \u0111\u1ed5i c\u1ee7a state. M\u1ed7i khi state thay \u0111\u1ed5i, widget s\u1ebd \u0111\u01b0\u1ee3c rebuild \u0111\u1ec3 hi\u1ec3n th\u1ecb gi\u00e1 tr\u1ecb counter m\u1edbi.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>T\u01b0\u01a1ng t\u00e1c ng\u01b0\u1eddi d\u00f9ng:<\/b><span style=\"font-weight: 400;\"> Khi ng\u01b0\u1eddi d\u00f9ng nh\u1ea5n v\u00e0o c\u00e1c n\u00fat, c\u00e1c event t\u01b0\u01a1ng \u1ee9ng \u0111\u01b0\u1ee3c g\u1eedi \u0111\u1ebfn <\/span><span style=\"font-weight: 400;\">CounterBloC<\/span><span style=\"font-weight: 400;\"> v\u00e0 qu\u00e1 tr\u00ecnh c\u1eadp nh\u1eadt state v\u00e0 giao di\u1ec7n \u0111\u01b0\u1ee3c l\u1eb7p l\u1ea1i.<\/span><\/li>\n<\/ul>\n<p><b>\u01afu \u0111i\u1ec3m c\u1ee7a vi\u1ec7c s\u1eed d\u1ee5ng BloC trong v\u00ed d\u1ee5 n\u00e0y:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>T\u00e1ch bi\u1ec7t m\u1ed1i quan t\u00e2m:<\/b><span style=\"font-weight: 400;\"> Logic t\u0103ng gi\u1ea3m counter \u0111\u01b0\u1ee3c t\u00e1ch bi\u1ec7t ho\u00e0n to\u00e0n v\u1edbi giao di\u1ec7n.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>D\u1ec5 ki\u1ec3m th\u1eed:<\/b><span style=\"font-weight: 400;\"> Ch\u00fang ta c\u00f3 th\u1ec3 d\u1ec5 d\u00e0ng vi\u1ebft c\u00e1c test case \u0111\u1ec3 ki\u1ec3m tra h\u00e0nh vi c\u1ee7a <\/span><span style=\"font-weight: 400;\">CounterBloC<\/span><span style=\"font-weight: 400;\">.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>D\u1ec5 b\u1ea3o tr\u00ec:<\/b><span style=\"font-weight: 400;\"> Code tr\u1edf n\u00ean r\u00f5 r\u00e0ng v\u00e0 d\u1ec5 hi\u1ec3u h\u01a1n.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>T\u00e1i s\u1eed d\u1ee5ng:<\/b> <span style=\"font-weight: 400;\">CounterBloC<\/span><span style=\"font-weight: 400;\"> c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng trong c\u00e1c ph\u1ea7n kh\u00e1c c\u1ee7a \u1ee9ng d\u1ee5ng.<\/span><\/li>\n<\/ul>\n<p><b>T\u00f3m l\u1ea1i<\/b><\/p>\n<p><span style=\"font-weight: 400;\">V\u00ed d\u1ee5 \u0111\u01a1n gi\u1ea3n n\u00e0y \u0111\u00e3 minh h\u1ecda c\u00e1ch s\u1eed d\u1ee5ng BloC \u0111\u1ec3 qu\u1ea3n l\u00fd tr\u1ea1ng th\u00e1i c\u1ee7a m\u1ed9t \u1ee9ng d\u1ee5ng Flutter. B\u1eb1ng c\u00e1ch t\u00e1ch bi\u1ec7t logic nghi\u1ec7p v\u1ee5 kh\u1ecfi giao di\u1ec7n, ch\u00fang ta c\u00f3 th\u1ec3 x\u00e2y d\u1ef1ng c\u00e1c \u1ee9ng d\u1ee5ng Flutter m\u1ed9t c\u00e1ch hi\u1ec7u qu\u1ea3 v\u00e0 d\u1ec5 b\u1ea3o tr\u00ec.<\/span><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Thuc_hanh_BloC_Flutter_nang_cao\"><\/span><strong>Th\u1ef1c h\u00e0nh BloC Flutter n\u00e2ng cao<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><strong>S\u1eed d\u1ee5ng BloC v\u1edbi RxDart<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">RxDart cung c\u1ea5p m\u1ed9t b\u1ed9 c\u00f4ng c\u1ee5 m\u1ea1nh m\u1ebd \u0111\u1ec3 l\u00e0m vi\u1ec7c v\u1edbi c\u00e1c lu\u1ed3ng d\u1eef li\u1ec7u (streams) trong Dart. Khi k\u1ebft h\u1ee3p v\u1edbi BloC, RxDart gi\u00fap qu\u1ea3n l\u00fd c\u00e1c s\u1ef1 ki\u1ec7n v\u00e0 tr\u1ea1ng th\u00e1i m\u1ed9t c\u00e1ch hi\u1ec7u qu\u1ea3 h\u01a1n.<\/span><\/p>\n<p><b>C\u00e1c l\u1ee3i \u00edch khi k\u1ebft h\u1ee3p BloC v\u1edbi RxDart:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Bi\u1ec3u di\u1ec5n d\u1eef li\u1ec7u theo th\u1eddi gian:<\/b><span style=\"font-weight: 400;\"> RxDart cho ph\u00e9p b\u1ea1n m\u00f4 h\u00ecnh h\u00f3a d\u1eef li\u1ec7u thay \u0111\u1ed5i theo th\u1eddi gian, r\u1ea5t ph\u00f9 h\u1ee3p v\u1edbi c\u00e1c \u1ee9ng d\u1ee5ng ph\u1ea3n \u1ee9ng nh\u01b0 Flutter.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>C\u00e1c to\u00e1n t\u1eed:<\/b><span style=\"font-weight: 400;\"> RxDart cung c\u1ea5p m\u1ed9t lo\u1ea1t c\u00e1c to\u00e1n t\u1eed \u0111\u1ec3 bi\u1ebfn \u0111\u1ed5i v\u00e0 k\u1ebft h\u1ee3p c\u00e1c streams, gi\u00fap b\u1ea1n vi\u1ebft code ng\u1eafn g\u1ecdn v\u00e0 d\u1ec5 \u0111\u1ecdc h\u01a1n.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Qu\u1ea3n l\u00fd l\u1ed7i:<\/b><span style=\"font-weight: 400;\"> RxDart c\u00f3 c\u00e1c c\u01a1 ch\u1ebf x\u1eed l\u00fd l\u1ed7i m\u1ea1nh m\u1ebd, gi\u00fap b\u1ea1n \u0111\u1ea3m b\u1ea3o \u1ee9ng d\u1ee5ng lu\u00f4n ho\u1ea1t \u0111\u1ed9ng \u1ed5n \u0111\u1ecbnh.<\/span><\/li>\n<\/ul>\n<pre>import 'package: bloc\/bloc.dart';\r\nimport 'package:rxdart\/rxdart.dart';\r\n\r\nclass Counter Bloc extends Bloc&lt;Counter Event, int&gt; {\r\n  CounterBloc(): super(0) {\r\n    on&lt;IncrementEvent&gt;((event, emit) =&gt; emit (state + 1));\r\n  }\r\n}\r\n\r\nclass IncrementEvent {}<\/pre>\n<h3><strong>K\u1ebft h\u1ee3p BloC v\u1edbi c\u00e1c th\u01b0 vi\u1ec7n kh\u00e1c<\/strong><\/h3>\n<p><b>Repository:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">T\u00e1ch bi\u1ec7t logic truy c\u1eadp d\u1eef li\u1ec7u: Repository l\u00e0 m\u1ed9t l\u1edbp tr\u1eebu t\u01b0\u1ee3ng cung c\u1ea5p m\u1ed9t giao di\u1ec7n \u0111\u1ec3 truy c\u1eadp d\u1eef li\u1ec7u t\u1eeb c\u00e1c ngu\u1ed3n kh\u00e1c nhau (database, API, &#8230;).<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">C\u1ea3i thi\u1ec7n kh\u1ea3 n\u0103ng test: Vi\u1ec7c t\u00e1ch bi\u1ec7t logic truy c\u1eadp d\u1eef li\u1ec7u gi\u00fap b\u1ea1n d\u1ec5 d\u00e0ng vi\u1ebft c\u00e1c unit test cho BloC.<\/span><\/li>\n<\/ul>\n<p><b>API Client:<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Truy c\u1eadp d\u1eef li\u1ec7u t\u1eeb server: API client l\u00e0 m\u1ed9t l\u1edbp gi\u00fap b\u1ea1n th\u1ef1c hi\u1ec7n c\u00e1c y\u00eau c\u1ea7u HTTP \u0111\u1ec3 l\u1ea5y d\u1eef li\u1ec7u t\u1eeb server.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">X\u1eed l\u00fd l\u1ed7i: API client th\u01b0\u1eddng c\u00f3 c\u00e1c c\u01a1 ch\u1ebf x\u1eed l\u00fd l\u1ed7i nh\u01b0 timeouts, errors, &#8230;<\/span><\/li>\n<\/ul>\n<h3><strong>X\u1eed l\u00fd l\u1ed7i trong BloC<\/strong><\/h3>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>CatchError:<\/b><span style=\"font-weight: 400;\"> S\u1eed d\u1ee5ng to\u00e1n t\u1eed <\/span><span style=\"font-weight: 400;\">catchError<\/span><span style=\"font-weight: 400;\"> c\u1ee7a RxDart \u0111\u1ec3 b\u1eaft c\u00e1c l\u1ed7i x\u1ea3y ra trong qu\u00e1 tr\u00ecnh x\u1eed l\u00fd event.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>MapEventToState:<\/b><span style=\"font-weight: 400;\"> X\u1eed l\u00fd l\u1ed7i ngay trong h\u00e0m <\/span><span style=\"font-weight: 400;\">mapEventToState<\/span><span style=\"font-weight: 400;\"> c\u1ee7a BloC.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Custom Error State:<\/b><span style=\"font-weight: 400;\"> T\u1ea1o m\u1ed9t tr\u1ea1ng th\u00e1i ri\u00eang \u0111\u1ec3 bi\u1ec3u di\u1ec5n l\u1ed7i v\u00e0 hi\u1ec3n th\u1ecb th\u00f4ng b\u00e1o cho ng\u01b0\u1eddi d\u00f9ng.<\/span><\/li>\n<\/ul>\n<pre>class Counter Bloc extends Bloc&lt;Counter Event, int&gt; {\r\n  CounterBloc(): super(0) {\r\n    on&lt;IncrementEvent&gt;((event, emit) async {\r\n      try {\r\n        \/\/ Logic t\u0103ng gi\u00e1 tr\u1ecb\r\n        emit(state + 1);\r\n      } catch (e) {\r\n        \/\/ X\u1eed l\u00fd l\u1ed7i\r\n        emit(state);\r\n      }\r\n    });\r\n  }\r\n}<\/pre>\n<h3><strong>Ki\u1ec3m th\u1eed BloC<\/strong><\/h3>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Unit test: Ki\u1ec3m tra t\u1eebng ph\u1ea7n c\u1ee7a BloC m\u1ed9t c\u00e1ch \u0111\u1ed9c l\u1eadp.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Widget test: Ki\u1ec3m tra c\u00e1ch BloC t\u01b0\u01a1ng t\u00e1c v\u1edbi c\u00e1c widget.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Integration test: Ki\u1ec3m tra to\u00e0n b\u1ed9 \u1ee9ng d\u1ee5ng, bao g\u1ed3m c\u1ea3 BloC v\u00e0 c\u00e1c th\u00e0nh ph\u1ea7n kh\u00e1c.<\/span><\/li>\n<\/ul>\n<pre>import 'package: flutter_test\/flutter_test.dart';\r\nimport 'package:bloc_test\/bloc_test.dart';\r\nimport 'package: my app\/counter_bloc.dart';\r\n\r\nvoid main() {\r\n  group('Counter Bloc', () {\r\n    test('increments state', () async {\r\n      final bloc = Counter Bloc();\r\n      await expectLater (\r\n        bloc,\r\n        emitsInOrder ([\r\n          0,\r\n          1,\r\n        ]),\r\n      );\r\n      bloc.add(IncrementEvent());\r\n      await bloc.close();\r\n    });\r\n  });\r\n}<\/pre>\n<h3><b>T\u00f3m l\u1ea1i<\/b><\/h3>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">S\u1eed d\u1ee5ng RxDart: T\u0103ng c\u01b0\u1eddng kh\u1ea3 n\u0103ng qu\u1ea3n l\u00fd lu\u1ed3ng d\u1eef li\u1ec7u v\u00e0 x\u1eed l\u00fd c\u00e1c s\u1ef1 ki\u1ec7n ph\u1ee9c t\u1ea1p.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">K\u1ebft h\u1ee3p v\u1edbi c\u00e1c th\u01b0 vi\u1ec7n kh\u00e1c: T\u00e1ch bi\u1ec7t c\u00e1c ph\u1ea7n quan tr\u1ecdng c\u1ee7a \u1ee9ng d\u1ee5ng, t\u0103ng kh\u1ea3 n\u0103ng t\u00e1i s\u1eed d\u1ee5ng v\u00e0 b\u1ea3o tr\u00ec.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">X\u1eed l\u00fd l\u1ed7i hi\u1ec7u qu\u1ea3: \u0110\u1ea3m b\u1ea3o \u1ee9ng d\u1ee5ng lu\u00f4n ho\u1ea1t \u0111\u1ed9ng \u1ed5n \u0111\u1ecbnh, ngay c\u1ea3 khi x\u1ea3y ra l\u1ed7i.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Vi\u1ebft c\u00e1c test case: \u0110\u1ea3m b\u1ea3o ch\u1ea5t l\u01b0\u1ee3ng code v\u00e0 ph\u00e1t hi\u1ec7n l\u1ed7i s\u1edbm.<\/span><\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Cac_cau_hoi_thuong_gap_ve_BloC_Flutter\"><\/span><strong>C\u00e1c c\u00e2u h\u1ecfi th\u01b0\u1eddng g\u1eb7p v\u1ec1 BloC Flutter<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><b>BloC Flutter l\u00e0 g\u00ec?<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">BloC, vi\u1ebft t\u1eaft c\u1ee7a Business Logic Component, l\u00e0 m\u1ed9t m\u00f4 h\u00ecnh qu\u1ea3n l\u00fd state gi\u00fap t\u00e1ch bi\u1ec7t logic nghi\u1ec7p v\u1ee5 kh\u1ecfi giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng trong \u1ee9ng d\u1ee5ng Flutter. BloC gi\u00fap c\u1ea3i thi\u1ec7n kh\u1ea3 n\u0103ng ki\u1ec3m tra, kh\u1ea3 n\u0103ng m\u1edf r\u1ed9ng, v\u00e0 t\u0103ng t\u00ednh d\u1ec5 b\u1ea3o tr\u00ec c\u1ee7a \u1ee9ng d\u1ee5ng b\u1eb1ng c\u00e1ch qu\u1ea3n l\u00fd state v\u00e0 c\u00e1c s\u1ef1 ki\u1ec7n m\u1ed9t c\u00e1ch r\u00f5 r\u00e0ng v\u00e0 c\u00f3 t\u1ed5 ch\u1ee9c.<\/span><\/p>\n<blockquote><p><em>\u0110\u1ecdc th\u00eam: <a href=\"https:\/\/itviec.com\/blog\/lap-trinh-flutter\/\" target=\"_blank\" rel=\"noopener\"><strong>L\u1eadp tr\u00ecnh Flutter: H\u01b0\u1edbng d\u1eabn c\u00e1ch ph\u00e1t tri\u1ec3n \u1ee9ng d\u1ee5ng v\u1edbi Flutter<\/strong><\/a><\/em><\/p><\/blockquote>\n<h3><b>C\u00e1c l\u1ee3i \u00edch c\u1ee7a vi\u1ec7c s\u1eed d\u1ee5ng BloC Flutter l\u00e0 g\u00ec?<\/b><\/h3>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">T\u0103ng kh\u1ea3 n\u0103ng \u0111\u1ecdc v\u00e0 b\u1ea3o tr\u00ec code: Code tr\u1edf n\u00ean r\u00f5 r\u00e0ng h\u01a1n, d\u1ec5 hi\u1ec3u h\u01a1n.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Qu\u1ea3n l\u00fd tr\u1ea1ng th\u00e1i ph\u1ee9c t\u1ea1p d\u1ec5 d\u00e0ng: BloC gi\u00fap b\u1ea1n x\u1eed l\u00fd c\u00e1c tr\u1ea1ng th\u00e1i ph\u1ee9c t\u1ea1p.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">T\u00e1i s\u1eed d\u1ee5ng code: C\u00e1c BloC c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c t\u00e1i s\u1eed d\u1ee5ng trong nhi\u1ec1u ph\u1ea7n kh\u00e1c nhau c\u1ee7a \u1ee9ng d\u1ee5ng.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">C\u1ea3i thi\u1ec7n hi\u1ec7u su\u1ea5t: Nh\u1edd c\u01a1 ch\u1ebf stream, c\u00e1c widget ch\u1ec9 \u0111\u01b0\u1ee3c c\u1eadp nh\u1eadt khi c\u00f3 s\u1ef1 thay \u0111\u1ed5i tr\u1ea1ng th\u00e1i.<\/span><\/li>\n<\/ul>\n<h3><b>Khi n\u00e0o n\u00ean s\u1eed d\u1ee5ng BloC v\u00e0 khi n\u00e0o n\u00ean s\u1eed d\u1ee5ng c\u00e1c ph\u01b0\u01a1ng ph\u00e1p qu\u1ea3n l\u00fd state kh\u00e1c?<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">BloC ph\u00f9 h\u1ee3p v\u1edbi c\u00e1c \u1ee9ng d\u1ee5ng c\u00f3 logic ph\u1ee9c t\u1ea1p, nhi\u1ec1u state v\u00e0 c\u1ea7n qu\u1ea3n l\u00fd lu\u1ed3ng d\u1eef li\u1ec7u m\u1ed9t c\u00e1ch r\u00f5 r\u00e0ng. \u0110\u1ed1i v\u1edbi c\u00e1c \u1ee9ng d\u1ee5ng \u0111\u01a1n gi\u1ea3n, b\u1ea1n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng c\u00e1c ph\u01b0\u01a1ng ph\u00e1p kh\u00e1c nh\u01b0 setState ho\u1eb7c Provider.<\/span><\/p>\n<p>T\u00f3m l\u1ea1i, n\u00ean s\u1eed d\u1ee5ng BloC Flutter khi:<\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">C\u00e1c \u1ee9ng d\u1ee5ng c\u00f3 logic nghi\u1ec7p v\u1ee5 ph\u1ee9c t\u1ea1p.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">C\u00e1c \u1ee9ng d\u1ee5ng c\u1ea7n qu\u1ea3n l\u00fd nhi\u1ec1u tr\u1ea1ng th\u00e1i kh\u00e1c nhau.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">C\u00e1c \u1ee9ng d\u1ee5ng y\u00eau c\u1ea7u hi\u1ec7u su\u1ea5t cao.<\/span><\/li>\n<\/ul>\n<h3><b>L\u00e0m th\u1ebf n\u00e0o \u0111\u1ec3 truy\u1ec1n d\u1eef li\u1ec7u t\u1eeb BloC \u0111\u1ebfn widget?<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">B\u1ea1n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng c\u00e1c th\u01b0 vi\u1ec7n nh\u01b0 flutter_BloC ho\u1eb7c provider \u0111\u1ec3 cung c\u1ea5p BloC cho widget con v\u00e0 s\u1eed d\u1ee5ng BloCBuilder ho\u1eb7c Consumer \u0111\u1ec3 x\u00e2y d\u1ef1ng giao di\u1ec7n d\u1ef1a tr\u00ean state c\u1ee7a BloC.<\/span><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Tong_ket_BloC_Flutter\"><\/span><strong>T\u1ed5ng k\u1ebft BloC Flutter<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><span style=\"font-weight: 400;\">BloC Flutter l\u00e0 m\u1ed9t trong nh\u1eefng m\u00f4 h\u00ecnh qu\u1ea3n l\u00fd state m\u1ea1nh m\u1ebd v\u00e0 linh ho\u1ea1t nh\u1ea5t trong Flutter, gi\u00fap t\u00e1ch bi\u1ec7t r\u00f5 r\u00e0ng gi\u1eefa logic nghi\u1ec7p v\u1ee5 v\u00e0 giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng. V\u1edbi vi\u1ec7c s\u1eed d\u1ee5ng c\u00e1c event v\u00e0 state, BloC cung c\u1ea5p m\u1ed9t c\u01a1 ch\u1ebf r\u00f5 r\u00e0ng v\u00e0 c\u00f3 t\u1ed5 ch\u1ee9c \u0111\u1ec3 qu\u1ea3n l\u00fd state, \u0111\u1ed3ng th\u1eddi gi\u00fap c\u1ea3i thi\u1ec7n kh\u1ea3 n\u0103ng ki\u1ec3m tra, b\u1ea3o tr\u00ec v\u00e0 m\u1edf r\u1ed9ng c\u1ee7a \u1ee9ng d\u1ee5ng. B\u1eb1ng c\u00e1ch t\u1eadn d\u1ee5ng Streams, BloC cho ph\u00e9p qu\u1ea3n l\u00fd lu\u1ed3ng d\u1eef li\u1ec7u b\u1ea5t \u0111\u1ed3ng b\u1ed9 m\u1ed9t c\u00e1ch hi\u1ec7u qu\u1ea3, \u0111\u1ea3m b\u1ea3o giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng lu\u00f4n ph\u1ea3n \u00e1nh ch\u00ednh x\u00e1c tr\u1ea1ng th\u00e1i hi\u1ec7n t\u1ea1i c\u1ee7a \u1ee9ng d\u1ee5ng.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">D\u00f9 b\u1ea1n \u0111ang ph\u00e1t tri\u1ec3n m\u1ed9t \u1ee9ng d\u1ee5ng nh\u1ecf hay m\u1ed9t h\u1ec7 th\u1ed1ng ph\u1ee9c t\u1ea1p, BloC c\u00f3 th\u1ec3 l\u00e0 m\u1ed9t l\u1ef1a ch\u1ecdn ph\u00f9 h\u1ee3p \u0111\u1ec3 qu\u1ea3n l\u00fd state v\u00e0 logic nghi\u1ec7p v\u1ee5. Tuy nhi\u00ean, vi\u1ec7c l\u1ef1a ch\u1ecdn m\u00f4 h\u00ecnh qu\u1ea3n l\u00fd state c\u1ea7n ph\u1ea3i d\u1ef1a tr\u00ean y\u00eau c\u1ea7u c\u1ee5 th\u1ec3 c\u1ee7a d\u1ef1 \u00e1n v\u00e0 hi\u1ec3u r\u00f5 c\u00e1c \u01b0u v\u00e0 nh\u01b0\u1ee3c \u0111i\u1ec3m c\u1ee7a t\u1eebng gi\u1ea3i ph\u00e1p. BloC, v\u1edbi c\u1ed9ng \u0111\u1ed3ng m\u1ea1nh m\u1ebd v\u00e0 t\u00e0i li\u1ec7u phong ph\u00fa, l\u00e0 m\u1ed9t c\u00f4ng c\u1ee5 \u0111\u00e1ng \u0111\u1ec3 kh\u00e1m ph\u00e1 v\u00e0 \u00e1p d\u1ee5ng trong c\u00e1c d\u1ef1 \u00e1n Flutter c\u1ee7a b\u1ea1n.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>B\u00e0i vi\u1ebft &#8220;BloC Flutter&#8221; sau \u0111\u00e2y gi\u1edbi thi\u1ec7u m\u00f4 h\u00ecnh qu\u1ea3n l\u00fd tr\u1ea1ng th\u00e1i BloC (Business Logic Component) trong c\u1ed9ng \u0111\u1ed3ng Flutter. B\u00e0i vi\u1ebft gi\u1ea3i th\u00edch kh\u00e1i ni\u1ec7m BloC, c\u00e1ch t\u00e1ch bi\u1ec7t logic nghi\u1ec7p v\u1ee5 kh\u1ecfi giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng v\u00e0 t\u1ea7m quan tr\u1ecdng c\u1ee7a \u0111i\u1ec1u n\u00e0y trong ph\u00e1t tri\u1ec3n \u1ee9ng d\u1ee5ng. \u0110\u1ed3ng th\u1eddi, n\u00eau [&hellip;]<\/p>\n","protected":false},"author":203,"featured_media":77542,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_gspb_post_css":"","footnotes":""},"categories":[109],"tags":[],"class_list":["post-77295","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-chuyen-mon-it"],"blocksy_meta":[],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.8 (Yoast SEO v27.8) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>BloC Flutter: H\u01b0\u1edbng d\u1eabn chi ti\u1ebft c\u00e1ch s\u1eed d\u1ee5ng BloC trong Flutter - ITviec Blog<\/title>\n<meta name=\"description\" content=\"B\u00e0i vi\u1ebft gi\u1ea3i th\u00edch chi ti\u1ebft BloC Flutter, c\u00e1ch t\u00e1ch logic nghi\u1ec7p v\u1ee5 kh\u1ecfi giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng v\u00e0 t\u1ea7m quan tr\u1ecdng trong ph\u00e1t tri\u1ec3n \u1ee9ng d\u1ee5ng.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/\" \/>\n<meta property=\"og:locale\" content=\"vi_VN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"BloC Flutter: H\u01b0\u1edbng d\u1eabn chi ti\u1ebft c\u00e1ch s\u1eed d\u1ee5ng BloC trong Flutter\" \/>\n<meta property=\"og:description\" content=\"B\u00e0i vi\u1ebft &quot;BloC Flutter&quot; sau \u0111\u00e2y gi\u1edbi thi\u1ec7u m\u00f4 h\u00ecnh qu\u1ea3n l\u00fd tr\u1ea1ng th\u00e1i BloC (Business Logic Component) trong c\u1ed9ng \u0111\u1ed3ng Flutter. B\u00e0i vi\u1ebft gi\u1ea3i th\u00edch kh\u00e1i\" \/>\n<meta property=\"og:url\" content=\"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/\" \/>\n<meta property=\"og:site_name\" content=\"ITviec Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/ITviec\" \/>\n<meta property=\"article:published_time\" content=\"2024-08-29T09:50:01+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2024\/08\/bloc-flutter-vippro.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2850\" \/>\n\t<meta property=\"og:image:height\" content=\"1500\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Tien Tran\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ITviec\" \/>\n<meta name=\"twitter:site\" content=\"@ITviec\" \/>\n<meta name=\"twitter:label1\" content=\"\u0110\u01b0\u1ee3c vi\u1ebft b\u1edfi\" \/>\n\t<meta name=\"twitter:data1\" content=\"Tien Tran\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u01af\u1edbc t\u00ednh th\u1eddi gian \u0111\u1ecdc\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 ph\u00fat\" \/>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"BloC Flutter: H\u01b0\u1edbng d\u1eabn chi ti\u1ebft c\u00e1ch s\u1eed d\u1ee5ng BloC trong Flutter - ITviec Blog","description":"B\u00e0i vi\u1ebft gi\u1ea3i th\u00edch chi ti\u1ebft BloC Flutter, c\u00e1ch t\u00e1ch logic nghi\u1ec7p v\u1ee5 kh\u1ecfi giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng v\u00e0 t\u1ea7m quan tr\u1ecdng trong ph\u00e1t tri\u1ec3n \u1ee9ng d\u1ee5ng.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/","og_locale":"vi_VN","og_type":"article","og_title":"BloC Flutter: H\u01b0\u1edbng d\u1eabn chi ti\u1ebft c\u00e1ch s\u1eed d\u1ee5ng BloC trong Flutter","og_description":"B\u00e0i vi\u1ebft \"BloC Flutter\" sau \u0111\u00e2y gi\u1edbi thi\u1ec7u m\u00f4 h\u00ecnh qu\u1ea3n l\u00fd tr\u1ea1ng th\u00e1i BloC (Business Logic Component) trong c\u1ed9ng \u0111\u1ed3ng Flutter. B\u00e0i vi\u1ebft gi\u1ea3i th\u00edch kh\u00e1i","og_url":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/","og_site_name":"ITviec Blog","article_publisher":"https:\/\/www.facebook.com\/ITviec","article_published_time":"2024-08-29T09:50:01+00:00","og_image":[{"width":2850,"height":1500,"url":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2024\/08\/bloc-flutter-vippro.png","type":"image\/png"}],"author":"Tien Tran","twitter_card":"summary_large_image","twitter_creator":"@ITviec","twitter_site":"@ITviec","twitter_misc":{"\u0110\u01b0\u1ee3c vi\u1ebft b\u1edfi":"Tien Tran","\u01af\u1edbc t\u00ednh th\u1eddi gian \u0111\u1ecdc":"21 ph\u00fat"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#article","isPartOf":{"@id":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/"},"author":{"name":"Tien Tran","@id":"https:\/\/itviec.com\/blog\/#\/schema\/person\/1595d671c49cfa2a48cd3c0a047a1298"},"headline":"BloC Flutter: H\u01b0\u1edbng d\u1eabn chi ti\u1ebft c\u00e1ch s\u1eed d\u1ee5ng BloC trong Flutter","datePublished":"2024-08-29T09:50:01+00:00","mainEntityOfPage":{"@id":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/"},"wordCount":5576,"publisher":{"@id":"https:\/\/itviec.com\/blog\/#organization"},"image":{"@id":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#primaryimage"},"thumbnailUrl":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2024\/08\/bloc-flutter-vippro.png","articleSection":["Chuy\u00ean m\u00f4n IT"],"inLanguage":"vi"},{"@type":"WebPage","@id":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/","url":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/","name":"BloC Flutter: H\u01b0\u1edbng d\u1eabn chi ti\u1ebft c\u00e1ch s\u1eed d\u1ee5ng BloC trong Flutter - ITviec Blog","isPartOf":{"@id":"https:\/\/itviec.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#primaryimage"},"image":{"@id":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#primaryimage"},"thumbnailUrl":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2024\/08\/bloc-flutter-vippro.png","datePublished":"2024-08-29T09:50:01+00:00","description":"B\u00e0i vi\u1ebft gi\u1ea3i th\u00edch chi ti\u1ebft BloC Flutter, c\u00e1ch t\u00e1ch logic nghi\u1ec7p v\u1ee5 kh\u1ecfi giao di\u1ec7n ng\u01b0\u1eddi d\u00f9ng v\u00e0 t\u1ea7m quan tr\u1ecdng trong ph\u00e1t tri\u1ec3n \u1ee9ng d\u1ee5ng.","breadcrumb":{"@id":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#breadcrumb"},"inLanguage":"vi","potentialAction":[{"@type":"ReadAction","target":["https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/"]}]},{"@type":"ImageObject","inLanguage":"vi","@id":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#primaryimage","url":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2024\/08\/bloc-flutter-vippro.png","contentUrl":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2024\/08\/bloc-flutter-vippro.png","width":2850,"height":1500,"caption":"bloc flutter - itviec blog"},{"@type":"BreadcrumbList","@id":"https:\/\/itviec.com\/blog\/bloc-flutter-la-gi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Chuy\u00ean m\u00f4n IT","item":"https:\/\/itviec.com\/blog\/chuyen-mon-it\/"},{"@type":"ListItem","position":2,"name":"BloC Flutter: H\u01b0\u1edbng d\u1eabn chi ti\u1ebft c\u00e1ch s\u1eed d\u1ee5ng BloC trong Flutter"}]},{"@type":"WebSite","@id":"https:\/\/itviec.com\/blog\/#website","url":"https:\/\/itviec.com\/blog\/","name":"ITviec Blog","description":"IT Jobs &amp; People in Vietnam","publisher":{"@id":"https:\/\/itviec.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/itviec.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"vi"},{"@type":"Organization","@id":"https:\/\/itviec.com\/blog\/#organization","name":"ITviec","url":"https:\/\/itviec.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"vi","@id":"https:\/\/itviec.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2018\/12\/itviec-black-square-facebook.png","contentUrl":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2018\/12\/itviec-black-square-facebook.png","width":1800,"height":1800,"caption":"ITviec"},"image":{"@id":"https:\/\/itviec.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/ITviec","https:\/\/x.com\/ITviec","https:\/\/www.linkedin.com\/company\/itviec","https:\/\/www.youtube.com\/channel\/UCYthAQ3bcGr57M_ag5gHDvQ"]},{"@type":"Person","@id":"https:\/\/itviec.com\/blog\/#\/schema\/person\/1595d671c49cfa2a48cd3c0a047a1298","name":"Tien Tran","image":{"@type":"ImageObject","inLanguage":"vi","@id":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2024\/05\/tien-tran-author-e1715658627643-100x100.jpg","url":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2024\/05\/tien-tran-author-e1715658627643-100x100.jpg","contentUrl":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2024\/05\/tien-tran-author-e1715658627643-100x100.jpg","caption":"Tien Tran"},"url":"https:\/\/itviec.com\/blog\/author\/tien-tran\/"}]}},"_links":{"self":[{"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/posts\/77295","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/users\/203"}],"replies":[{"embeddable":true,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/comments?post=77295"}],"version-history":[{"count":0,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/posts\/77295\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/media\/77542"}],"wp:attachment":[{"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/media?parent=77295"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/categories?post=77295"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/tags?post=77295"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}