1. 程式人生 > >AngularJS scope銷燬事件,directive、controller等

AngularJS scope銷燬事件,directive、controller等

$destroy

 demo一隻

<!DOCTYPE html>
<html ng-app="app">
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>angular-demo</title>
</head>
<body>
<style>

</style>
<div ng-controller="ctrl as vm">
    {{vm.loading}}
    <button async-click="vm.log();submit();submit2();submit3();" :loading="vm.loading" ng-if="haha">測試</button>
    <input type="checkbox" ng-model="haha">
</div>
<script src="//apps.bdimg.com/libs/angular.js/1.3.13/angular.min.js?ver=96"></script>
<script>
	const application = angular.module('app', []);
	application
		.directive('asyncClick', function ($parse) {
			/**
			 * 回撥函式需要返回promise物件
			 * */
			return {
				restrict: 'A',
				scope: {
					callbackNames: '@asyncClick',
					loading: '=loading',
				},
				link(scope, el, property) {
					const callbacks = [];
					const promiseQueue = [];
					//獲取回撥函式
					getCallbacks();
					//註冊函式
					bindEvent();
					//指令銷燬事件
					scope.$on("$destroy", function () {
						unBindEvent();
					});

					//functions
					function getCallbacks() {
						scope.callbackNames.split(';').forEach(v => {
							v && callbacks.push($parse(v));
						});
					}

					function bindEvent() {
						el[0].addEventListener('click', handler);
					}

					function unBindEvent() {
						el[0].removeEventListener('click', handler);
					}

					function handler() {
						callbackRunStart();
						if (promiseQueue.length) return console.info(promiseQueue.length, '個事件未完成');
						callbacks.forEach(fn => {
							let p = fn(scope.$parent);
							p && p['then'] && promiseQueue.push(p);
						});
						//等全部事件完成
						let pCount = promiseQueue.length;
						promiseQueue.forEach(p => {
							p.finally(() => {
								if (--pCount === 0) {
									callbackRunSuccess();
								}
							});
						});
					}

					function callbackRunStart() {
						scope.$apply(function () {
							scope.loading = true;
						});
					}

					function callbackRunSuccess() {
						setTimeout(() => {//fix $q是內建服務
							scope.$apply(function () {
								scope.loading = false;
								promiseQueue.length = 0;
							});
						});
					}
				},
			};
		})
		.controller('ctrl', function ($scope, $http, $q) {
			const vm = this;
			vm.loading = false;
			vm.log = function () {
				console.log(2);
			};
			$scope.haha = true;
			$scope.submit = function () {
				return new Promise(resolve => {
					setTimeout(resolve, 3000);
				});
			};
			$scope.submit2 = function () {
				return $http.get('.');
			};
			$scope.submit3 = function () {
				const defer = $q.defer();
				setTimeout(defer.reject, 3000);
				return defer.promise;
			};
		});
</script>
</body>
</html>