文章目录
  1. 1. $compile
    1. 1.1. angular中页面处理
    2. 1.2. $compile服务
    3. 1.3. 参考
  2. 2. 确认弹窗服务
    1. 2.1. 存在问题
    2. 2.2. AlertMsg.ts
    3. 2.3. alertMsg.directive.ts
    4. 2.4. alertMsg.template.html
    5. 2.5. 在登录时使用
  3. 3. 结束语

AngularJS(v1.5.8)已经成为项目们的基本框架,《玩转Angular1》系列用于记录项目中的一些好玩或者比较特别的思路。
本文简单介绍angular的$compile服务,同时实现动态创建指令的过程。

$compile


angular中页面处理

ng对页面的处理过程:

  • 浏览器把HTML字符串解析成DOM结构
  • ng把DOM结构给$compile,返回一个link函数
  • 传入具体的scope调用这个link函数
  • 得到处理后的DOM,这个DOM处理了指令,连接了数据

$compile服务

$compile是个编译服务。编译服务主要是为指令编译DOM元素。
编译一段HTML字符串或者DOM的模板,产生一个将scope和模板连接到一起的函数。

$compile用法:

1
$compile(element,transclude,maxPriority);
  • element:将要被编译和插入模板的元素或者HTML字符串
  • transclude:指令内有效的函数。Function(angular.Scope,cloneAttachFn=)
  • maxPriority:只有在指令比给定的优先级低时应用。只影响根元素,不影响子元素

返回一个用于绑定HTML模板到一个作用域的连接函数,此时我们需要再次传入作用域scope,则将scope和模板连接到一起。

参考

确认弹窗服务


存在问题

上一节《玩转Angular1(13)–服务与指令的配合使用》中,我们使用ES6的modules来创建弹窗确认的服务,这样会存在以下的问题:

  1. 需要在index.html或者其他模板中插入该弹窗。
  2. 无法实现多层弹窗的确认,只能同时出现一个弹窗。

这里,我们可以通过将服务注入angular(即调用ngModule.service或者ngModule.factory),来获取$compile服务。
我们需要实现的功能:

  • 每次调用AlertMsg服务,返回一个Promise,可使用.then()方法
  • 可通过配置needComfirm设置是否需要二次确认
  • 弹窗动态创建,使用完后注销

AlertMsg.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// app/shared/services/AlertMsg.ts
// 提示确认弹窗
// SetAlertMsg({
// confirmText: '我是确认键',
// cancelText: '我是取消键',
// title: '我是头部',
// text: '我是说明文字文字文字',
// needConfirm: true/false
// }).then(() => {
// console.log('点击了确定');
// }, () => {
// console.log('关闭');
// });
interface IAlertMsg {
confirmText?: string;
cancelText?: string;
title?: string;
needConfirm?: boolean;
text: string;
}
class AlertMsgService {
$compile: any;
$rootScope: any;
constructor($compile, $rootScope) {
this.$compile = $compile;
this.$rootScope = $rootScope;
}
// 设置参数,并返回promise
setMsg(scope, params: IAlertMsg) {
// 创建新的作用域,用于编译指令
let newScope = this.$rootScope.$new();
// 创建新的Promise,并将回调传入作用域
const promise = new Promise((resolve, reject) => {
newScope.reject = reject;
newScope.resolve = resolve;
});
// 传入数据
newScope.params = params;
// 模板
const tmp = '<aside alert-msg params="params" reject="reject" resolve="resolve"></aside>';
// 添加到页面中
$('body').append(this.$compile(tmp)(newScope));
return promise;
}
}
export default (ngModule) => {
// 注入$compile、$rootScope服务
ngModule.factory('AlertMsg', ['$compile', '$rootScope', function ($compile, $rootScope) {
return (scope, params) => new AlertMsgService($compile, $rootScope).setMsg(scope, params);
}]);
};

我们在编译新建指令模板的时候,需要连接作用域,这里我们通过$rootScope.$compile()(scope)进行这个操作。
同时,我们还需要在bootstrap.ts文件中注册服务,这里就不详细讲了。

alertMsg.directive.ts

组件的使用当然也需要调整了,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
export default (ngModule) => {
ngModule.directive('alertMsg', ['AlertMsg', function (AlertMsg) {
return {
restrict: 'AE',
templateUrl: './shared/components/alertMsg.template.html',
transclude: true,
replace: true,
scope: {
params: '=',
reject: '=?',
resolve: '=?'
},
link(scope, element, attrs) {
// 关闭或者取消时,调用reject
scope.close = () => {
scope.reject();
element[0].remove();
};
// 确认时,调用resolve
scope.submit = () => {
// 若设置了再次确认,再次确认
if (scope.params && scope.params.needConfirm) {
AlertMsg(scope, { text: '再次确认?' }).then(() => {
scope.resolve();
element[0].remove();
}, () =>{
// 若需要取消上层的操作
// scope.close();
});
} else {
scope.resolve();
element[0].remove();
}
};
// 设置按下Esc键时默认取消
EscKeyUp(scope, () => {
scope.close();
});
}
};
}])
};

我们通过传入Promise的reject()resolve()方法,来控制确认和取消操作的回调。

alertMsg.template.html

1
2
3
4
5
6
7
8
9
10
11
12
<aside ng-show="params" class="alert-module confirm-msg" ng-click="close()">
<section ng-click="$event.stopPropagation()">
<header ng-show="params.title">{{ params.title }}</header>
<article>
<p ng-show="params.text">{{params.text}}</p>
</article>
<footer>
<a class="button-2" ng-click="submit()">{{params.confirmText || '确定'}}</a>
<a class="button-2 secondary" ng-click="close()">{{params.cancelText || '取消'}}</a>
</footer>
</section>
</aside>

在登录时使用

  • 注入依赖
  • 在登录的时候使用
1
2
3
4
5
6
// login.controller.ts
this.AlertMsg(this.$scope,{ text: '确认?', needConfirm: true }).then(() => {
// 登录
}, () =>{
// 取消
});

这样,我们就不需在index.html中全局注入指令。

结束语


这节主要简单介绍angular的$compile服务,以及在服务中动态编译创建指令的实现过程。
此处查看项目代码
此处查看页面效果

查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场边撸猫边学前端噢

码生艰难,写文不易,给我家猪囤点猫粮了喵~

作者:被删

出处:https://godbasin.github.io

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

文章目录
  1. 1. $compile
    1. 1.1. angular中页面处理
    2. 1.2. $compile服务
    3. 1.3. 参考
  2. 2. 确认弹窗服务
    1. 2.1. 存在问题
    2. 2.2. AlertMsg.ts
    3. 2.3. alertMsg.directive.ts
    4. 2.4. alertMsg.template.html
    5. 2.5. 在登录时使用
  3. 3. 结束语