前端开发框架总结之Angular实用技巧(六)
上文讲了Angular中依赖注入相关知识,掌握了这些,我们就可以在前端的逻辑更清晰明了,复用程度也更高。今天我们对Angular系列做一个收尾,把一些零零碎碎的小技巧总结下。
- 进程间通讯
我们使用事件的方式进行进程间的通讯。主要用到如下几个方法。$on,$emit,$broadcast.
$on,用来接收事件和参数。接收到得事件包括以下几个主要的属性,name(事件名称)、targetScope(发出时间的scope)、currentScope(接收事件的scope)、stopPropagation方法(阻止emit时间继续冒泡)
$emit, 用于向父scope发送事件。(发送事件所在的scope中也可以监听到,这个在自定义组件中可能会用到)
$broadcast 用于向子scope发送事件。(本身所在的scope也可以监听的到)
js代码:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>angular进程间通讯</title>
</head>
<body ng-app="ExampleApp">
<div ng-controller="parentCtrl">
<button ng-click="clickParent()" >parent</button>
<div ng-controller="child1Ctrl">
<button ng-click="clickChild()" >child1</button>
<div ng-controller="subChildCtrl">
<button ng-click="clickSubChild()" >subChild</button>
</div>
</div>
<div ng-controller="child2Ctrl">
</div>
</div>
<script src="jquery-3.2.1.min.js"></script>
<script src="angular.js"></script>
<script>
var app = angular.module('ExampleApp', []);
app.controller('parentCtrl',['$scope', function ($scope) {
console.log('enter parentCtrl');
var obj = new Object();
obj.data = 'from parent';
var test = 'testContent';
$scope.getObj = function () {
return test;
}
$scope.clickParent = function () {
$scope.$broadcast('parentEvent',obj);
}
$scope.$on('child1Event',function (event, args) {
});
$scope.$on('parentEvent',function (event, args) {
debugger;
});
}]);
app.controller('child1Ctrl',['$scope', function ($scope) {
console.log('enter child1Ctrl');
var obj = new Object();
obj.data = 'from child1';
$scope.clickChild = function () {
$scope.$emit('child1Event',obj);
}
$scope.$on('parentEvent',function (event, args) {
console.log('方法调用:' + $scope.getObj());
});
$scope.$on('child1Event',function (event, args) {
debugger;
});
$scope.$on('subChildEvent',function (event, args) {
debugger;
event.stopPropagation();
});
}]);
app.controller('child2Ctrl',['$scope', function ($scope) {
console.log('enter child2Ctrl');
$scope.$on('parentEvent',function (event, args) {
debugger;
});
$scope.$on('child1Event',function (event, args) {
debugger;
});
}]);
app.controller('subChildCtrl',['$scope', function ($scope) {
console.log('enter subChildCtrl');
var obj = new Object();
obj.data = 'from subChild';
$scope.$on('parentEvent',function (event, args) {
debugger;
});
$scope.$on('child1Event',function (event, args) {
debugger;
});
$scope.clickSubChild = function () {
$scope.$emit('subChildEvent',obj);
}
}]);
</script>
</body>
</html>
-
$interval使用
interval的使用本身没有什么难度,但是要注意防止放生内存泄露,因为interval发起的定时任务,如果不清除的话,会一直循环执行。方法如下
var timer = $interval(function () {
console.log('enter interval ')
},5000);
$scope.on('$destory',function () {
$interval.cancel(timer);
});
-
ng-if,ng-show
ng-if如果条件不满足是不会生成对应元素的,ng-show只是不显示对应元素而已。这个要根据实际情况使用的。
-
巧用ng-class ng-style
巧用ng-class,ng-style可以使我们尽可能少的直接操纵页面元素来实现页面的动态效果。
直接上例子
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>ng-class,ng-style巧用</title>
<style>
.myBtn{
height: 36px;
background-color: white;
border: 1px solid #f5f5f5;
}
.myBtn.select{
background-color: darkseagreen;
}
</style>
</head>
<body ng-app="ExampleApp">
<div ng-controller="testCtrl">
<div>
<button ng-click="clickBtn($event)" ng-class="{'myBtn':true,'select':btn[0].select}" data-index="0">选中我</button>
<button ng-click="clickBtn($event)" ng-class="{'myBtn':true,'select':btn[1].select}" data-index="1">选中我</button>
</div>
<div>
<button ng-style="myStyle" ng-click="changeStyle()">改变style</button>
</div>
</div>
<script src="jquery-3.2.1.min.js"></script>
<script src="angular.js"></script>
<script>
var app = angular.module('ExampleApp', []);
app.controller('testCtrl',['$scope', function ($scope) {
console.log('enter testCtrl');
$scope.btn = [
{
'select':false
},
{
'select':false
},
];
$scope.clickBtn = function (event) {
$scope.btn[event.target.dataset.index].select = !$scope.btn[event.target.dataset.index].select;
}
$scope.myStyle = {
'background':'red'
};
$scope.changeStyle = function () {
$scope.myStyle.background = 'yellow';
}
}]);
</script>
</body>
</html>
-
过滤器
过滤器分为原生自定的过滤器和自定义过滤器两种,过滤器可以用在表达式类型的绑定和ng-bind类型的绑定上,不能用在ng-model,如果想在ng-model实现类似功能可以使用自定义指令。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>angular过滤器使用</title>
<style>
.ng-cloak{
display: none;
}
</style>
</head>
<body ng-app="ExampleApp">
<div ng-controller="testCtrl" >
<div>
<span class="ng-cloak">{{testContent | uppercase}}</span>
</div>
<div>
<span ng-bind="testContent | reverse"></span>
</div>
</div>
<script src="jquery-3.2.1.min.js"></script>
<script src="angular.js"></script>
<script>
var app = angular.module('ExampleApp', []);
app.controller('testCtrl',['$scope', function ($scope) {
console.log('enter testCtrl');
$scope.testContent = 'aaa bbb ccc';
}]);
app.filter('reverse', function() { //可以注入依赖
return function (text) {
return text.split("").reverse().join("");
}
});
</script>
</body>
</html>
示例中的代码有一个防止加载页面时{{}}闪烁的解决技巧。
-
校验
校验分为自定校验和原生校验两种。直接上例子。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>angular-test</title>
</head>
<body ng-app="ExampleApp">
<div ng-controller="MainCtrl">
<form name="testForm">
<input name="test" ng-model="name" validate-name>
<div ng-show="testForm.test.$error.validRule">
输入内容不合法
</div>
</form>
</div>
<script src="jquery-3.2.1.min.js"></script>
<script src="angular.js"></script>
<script>
var app = angular.module('ExampleApp', []);
app.controller('MainCtrl', function ($scope,$timeout) {
$scope.name= '';
});
var INTEGER_REGEXP = /^[\u4E00-\u9FA5a-zA-Z0-9_]{0,20}$/;
app.directive('validateName',function () {
return {
restrict: 'A',
require:'?^ngModel',
link:function (scope,element,attrs,ngModel) {
ngModel.$validators.validRule = function (modelValue,viewValue) {
if(INTEGER_REGEXP.test(viewValue)){
return true;
}
return false;
}
}
}
});
</script>
</body>
</html>
-
使用$parsers和$formatters对内容进行转化
parsers是页面内容到model值得转化,formatter是从model到页面值得转化。直接上例子
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>angular ngModel的parser和formatter使用</title>
</head>
<body ng-app="ExampleApp">
<div ng-controller="testCtrl" >
<span>model的值:{{inputTest}}</span>
<div>
<input ng-model="inputTest" my-input>
</div>
<button ng-click="changeValue()">change</button>
</div>
<script src="jquery-3.2.1.min.js"></script>
<script src="angular.js"></script>
<script>
var app = angular.module('ExampleApp', []);
app.controller('testCtrl',['$scope', function ($scope) {
console.log('enter testCtrl');
$scope.inputTest = '';
$scope.changeValue = function () {
$scope.inputTest = "赋初值";
}
}]);
app.directive('myInput',function () {
return {
restrict: 'A',
require:'?^ngModel',
link:function (scope,element,attrs,ngModel) {
//把输入的值都默认的转化为大写。
ngModel.$parsers.push(function (value) {
value = value.toUpperCase();
return value;
});
ngModel.$formatters.push(function (value) {
if(value){
value = value + '转化后的值';
}
return value;
});
}
}
});
</script>
</body>
</html>
angular系列就到此为止,希望对大家有所帮助。