玩转Angular1(13)

文章目录

AngularJS(v1.5.8)已经成为项目们的基本框架,《玩转Angular1》系列用于记录项目中的一些好玩或者比较特别的思路。
本文简单介绍通过服务来调用Directive指令的过程。

确认弹窗服务


基本思路

有时候,我们需要在控制器逻辑中进行确认操作,例如删除、注销等一些操作,是需要用户进行确认的。
这时候我们想要这样的一个服务,用来进行确认操作:

  • 调用函数,传入title、text等参数,显示确认的信息
  • 函数返回一个Promise,可使用.then来进行后续的处理
  • then函数传入两个回调,分别是确认继续的回调,和取消的回调

我们的服务还需要对外提供以下功能:

  • 设置函数SetAlertMsg
  • 是否已设置弹窗isAlertMsgSet
  • 设置的数据GetAlertMsgParams
  • 取消函数AlertMsgReject
  • 确认函数AlertMsgResolve

后面的几个,主要是为了在指令中使用。

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// 提示确认弹窗
// SetAlertMsg({
// confirmText: '我是确认键',
// cancelText: '我是取消键',
// title: '我是头部',
// text: '我是说明文字文字文字',
// }).then(() => {
// console.log('点击了确定');
// }, () => {
// console.log('关闭');
// });
interface IAlertMsg {
confirmText?: string;
cancelText?: string;
title?: string;
icon?: string;
text: string;
}
class {
private isSet: boolean = false;
private params: IAlertMsg = undefined;
private resolve: any = undefined;
private reject: any = undefined;
constructor() {
// 单独提取方法需要绑定this
this.getIsSet = this.getIsSet.bind(this);
this.getParams = this.getParams.bind(this);
this.setMsg = this.setMsg.bind(this);
this.msgReject = this.msgReject.bind(this);
this.msgResolve = this.msgResolve.bind(this);
}
// 获取是否设置
getIsSet() {
return this.isSet;
}
// 获取设置的数据
getParams() {
return this.params;
}
// 设置参数,并返回promise
setMsg(params: IAlertMsg) {
this.isSet = true;
this.params = params;
return new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
// reject并清除数据
msgReject() {
if (typeof this.reject === 'function') { this.reject(); }
this.clearMsg();
}
// resolve并清除数据
msgResolve() {
if (typeof this.resolve === 'function') { this.resolve(); }
this.clearMsg();
}
// 清除数据
private clearMsg() {
this.params = undefined;
this.isSet = false;
}
}
const AlertMsg = new AlertMsgService();
const {getParams, getIsSet, setMsg, msgReject, msgResolve} = AlertMsg;
export {
getIsSet as isAlertMsgSet,
setMsg as SetAlertMsg,
getParams as GetAlertMsgParams,
msgReject as AlertMsgReject,
msgResolve as AlertMsgResolve,
};
export default AlertMsg;

确认弹窗组件


基本思路

弹窗组件需要满足的一些需求:

  • 获取弹窗服务的状态,来控制是否显示
  • 获取弹窗服务的数据,并进行相应的展示控制
  • 取消或关闭时,调用reject
  • 添加按键Esc事件,进行取消或关闭
  • 确认时,调用resolve回调

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
export default (ngModule) => {
ngModule.directive('alertMsg', ['$parse', function ($parse) {
return {
restrict: 'AE',
templateUrl: './alertMsg.template.html',
transclude: true,
replace: true,
link(scope, element, attrs) {
// watch是否设置,来控制是否显示
scope.$watch(isAlertMsgSet, function (newValue, oldValue) {
if (newValue === true) {
// 获取相应的现实数据
scope.params = GetAlertMsgParams();
// 设置按下Esc键时默认取消
EscKeyUp(scope, () => {
scope.close();
});
}
});
// 关闭或者取消时,调用reject
scope.close = () => {
AlertMsgReject();
scope.params = undefined;
};
// 确认时,调用resolve
scope.submit = () => {
AlertMsgResolve();
scope.params = undefined;
};
}
};
}])
};

关于EscKeyUp服务,有兴趣或者疑问的小伙伴可以到《玩转Angular1(9)–按键事件队列KeyUp服务》查看。

alertMsg.template.html

1
2
3
4
5
6
7
8
9
10
11
12
<aside ng-show="params" class="alert-module confirm-msg">
<section on-focus-lost="close()">
<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>

这里,若我们不传入title参数,是不会显示头部的,这也是配置的一种。
而关于[on-focus-lost]指令,前面《玩转Angular1(10)–使用Directive指令来添加事件监听》也提到过,其实这里我们的EscKeyUp服务,也可以转成[on-esc]指令来实现的。

注册指令并使用

  • bootstrap.ts启动文件中注册指令
1
2
3
4
5
6
...
import AlertDirective from './shared/components/alertMsg.directive';
[
...
AlertDirective
].forEach((service) => service(ngModule));
  • 在登录的时候使用
1
2
3
4
5
6
// login.controller.ts
SetAlertMsg({ text: '确认?' }).then(() => {
// 登录
}, () =>{
// 取消
});
  • index.html中全局注入指令
1
<aside alert-msg></aside>

效果图:
image

结束语


这节主要简单介绍服务和组件配合着使用的过程,当然其实要实现这样的设计,还有一些其他的方法,小伙伴们也可以去想一下啦。还可以把弹窗模块进行拓展,加入可配置输入框、选择框等等去做呢。
此处查看项目代码
此处查看页面效果

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