要實作的是一個簡單的Lightbox (或Modal),要練習的點是:
- 此外掛為一個Module,可引入至其他的AngularJS Module。
- 此Module提供一個Service,可以由引入此Module的程式呼叫使用。
- 此Module提供一個Directive,Directive可以與參數雙向(或單向,看需求)綁定,並且Directive可以呼叫上述Service來使用。
目標結果為:
- Lightbox外掛提供一個Service,可以開始及關閉Lightbox,並且可以在開啟Lightbox時提供要顯示在Lightbox中的文字。
- Lightbox外掛提供一個Directive,Directive經過設計,有提供一個按鈕,其被按下會執行Service的開啟lightbox功能,Directive可以給入參數,設定Lightbox中要顯示的文字。
- 開啟的Lightbox提供一個Close按鈕,按下可以關閉Lightbox。
- 一次只會有一個Lightbox被開啟。
其成品就像如下視頻那樣:
首先先 看一下檔案結構:
- /index.html:主要的網頁頁面。
- /js/index.js :index.html使用的JS,主要頁面的AngularJS邏輯。
- /js/angular.js : 要引入使用的angularjs。
- /js/myAngularJsPlugin.js : 要撰寫的自製Lightbox AngularJS Plugin。
- /index.html :
<!DOCTYPE html> <html> <head> <title>TODO supply a title</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="js/angular.js"></script> <script src="js/myAngularJsPlugin/myModalModule.js"></script> <script src="js/index.js"></script> </head> <body> <div ng-app="myApp" ng-controller="myController as myCtrl"> 可自行輸入要在Modal內顯示的文字 <div style="margin-bottom: 20px;"> <input type="text" ng-model="myCtrl.modalText"/> </div> 在Controller裡呼叫自製Module提供的Service來開啟Modal <div style="margin-bottom: 20px;"> <button ng-click="myCtrl.openModal(myCtrl.modalText)">Open Modal manually</button> </div> 使用自製Module提供的Directive來開啟Modal <div> <my-modal-directive modal-text="myCtrl.modalText"></my-modal-directive> </div> </div> </body> </html>
- /js/index.js :
angular.module("myApp", ["myModalModule"]); angular.module("myApp").controller("myController", ["myModalService", function(myModalService){ var self = this; self.modalText = "測試文字"; self.openModal = openModal; function openModal(modalText){ myModalService.open(modalText); } }]);
- /js/myAngularJsPlugin.js:
//Module angular.module("myModalModule", []); //Service angular.module("myModalModule").factory("myModalService", ["$rootScope", "$compile", function ($rootScope, $compile) { //設計一次只能有一個Modal開啟 var scope; var modal; var $body = angular.element(document).find('body'); var isModalOpened = false; //modal template中有跟angularjs scope有關的程式碼, //須要使用$compile編譯並與scope連結才能有作用 var modalTemplate = '<div style="position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; background-color: rgba(158, 158, 158, 0.68); ">' + '<button ng-click="close()" >Close</button>' + '<div style="display: flex; align-items: center; justify-content:center; width: 100%; height: 100%;">' + '{{textContent}}' + '</div>' + '</div>'; //functions function open(textContent) { if (!isModalOpened) { //創建暫時的scope scope = $rootScope.$new(); //在scope中設置close函式 scope.close = close; //在scope中設置textContent scope.textContent = textContent; //使用$compile來編譯modalTemplate,得到link函式,執行link函式並代入scope來與scope連結, //最後得到連結好的DOM modal = $compile(modalTemplate)(scope); //將得到的DOM加進<body>中 $body.append(modal); //設置modal opened狀態 isModalOpened = true; } } function close() { if (isModalOpened) { //將Modal DOM移除 modal.remove(); //移除暫時scope scope.$destroy(); //設置modal opened狀態 isModalOpened = false; } } //自製Service對外提供的API return { open: open, close: close }; }]); //Directive angular.module("myModalModule").directive("myModalDirective", ["myModalService", function (myModalService) { return { restrict: "E", replace: true, scope: { //自製Directive可接受modalText參數(為表達示) modalText: "=modalText" }, template: generateTemplate, link: function ($scope, $elm, $attrs, $ngModel) { $scope.openModal = myModalService.open; /* 以上寫法等同以下,上面雖簡潔但下面寫法可讀性比較好 $scope.openModal = function (modalText) { myModalService.open(modalText); } */ } }; function generateTemplate($elm, $attrs) { //用function回傳template,也可以直接用字串不用函式 return '<button ng-click="openModal(modalText)">Open Modal by Directive</button>'; } }]);
angularJS-servicePractice.7z
參考資料:
沒有留言 :
張貼留言