AngularJS scope銷燬事件,directive、controller等
阿新 • • 發佈:2018-11-07
$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>