目录

angular中的指令可谓是最复杂的一块

但是我们的上传组件就能这么写

效果图:

API概览

先上一段伪代码:

  1. angular.module('moduleName', []).directive(
  2. 'namespaceDirectiveName',
  3. [ function() {
  4. return {
  5. restrict : '',// 描述指令在模版中的使用方式,包括元素E,属性A,CSS样式类,注释或者以上方式的任意主和
  6. priority : 0,// 设置指令在模版中的执行顺序,顺序是相对于其他指令而言
  7. template : '',// 以字符串的形式编写一个内联模版,如果以url的形式提供模版,此属性会被忽略
  8. templateUrl : '',// 描述加载模版所需要的url。如果使用temlate形式提供模版,此属性会被忽略
  9. replace : true,// 如果设置为true则替换指令所在的元素,否则就追加到元素内部
  10. transclude : true,// 把指令元素原来的子节点移动到一个新模版内部
  11. scope : 'bool or object',// 为当前指令创建一个新的作用域,而不是使之继承父作用域
  12. constroller : function($scope, $element, $attrs, $transclude) {
  13. // 创建一个控制器,它会暴露一个API,利用这个API可以在多个指令之间进行通信
  14. },
  15. require : '',// 要求必须存在另个一指令,当前指令才能执行
  16. link : function(scope, iElement, iAttrs) {
  17. // 使用编程的方式修改最终生成的dom元素的实例,添加事件监听器,并设置数据绑定
  18. },
  19. compile : function(tElement, tAttrs, transclude) {
  20. //在使用ng-repeat用编程的方式修改dom模版,从而实现一个指令跨越多个指令的特性。
  21. //也可以返回一个link函数,可以用它来修改产生元素的示例
  22. return {
  23. pre : function preLink(scope, iElement, iAttrs,
  24. controller) {
  25. },
  26. post : function postLink(scope, iElement, iAttrs,
  27. controller) {
  28. }
  29.  
  30. }
  31. }
  32. };
  33. } ]);

这里重点介绍几个定义

restrict: 描述指令在模版中的使用方式,包括:元素、样式类、属性、注释,或者以上几种方式的任意组合。(默认为AE)

使用AngularUI.Bootstrap

GitHub:https://angular-ui.github.io/bootstrap/

Nuget:

Install-Package Angular.UI.Bootstrap(该库在Bootstrap3.3.7下测试通过,这里顺便说包中的带tpls.js实际就是自带了模板的js)

这里演示一个最常用到的Pager

  1. <link href="Content/bootstrap.min.css" rel="stylesheet" />
  2. </head>
  3. <body ng-app="ui.bootstrap.demo">
  4. <div ng-controller="PaginationDemoCtrl">
  5. <ul uib-pagination total-items="totalItems" previous-text="上页" next-text="下页" first-text="首页" last-text="末页" items-per-page="itemsPerPage" ng-model="currentPage" max-size="maxSize" class="pagination-sm" boundary-links="true" force-ellipses="true" ng-change="pageChanged()"></ul>
  6. </div>
  7. <script src="Scripts/angular.min.js"></script>
  8. <script src="Scripts/angular-ui/ui-bootstrap-tpls.min.js"></script>
  9. <script>
  10. angular.module('ui.bootstrap.demo', ['ui.bootstrap']).controller('PaginationDemoCtrl', function ($scope, $log) {
  11. $scope.totalItems = 1000;
  12. $scope.currentPage = 4;
  13. $scope.maxSize = 5;//显示分页码个数
  14. $scope.itemsPerPage = 20;//每页大小
  15.  
  16. $scope.pageChanged = function () {
  17. $log.log('Page changed to: ' + $scope.currentPage);
  18. };
  19. });
  20. </script>
  21. </body>

更多需要ui-bootstrap的其他插件 访问对应的GitHub Pages

自定义指令

对于restrict,template,replace,transclude并不复杂,本节不做过多赘述.

scope

scope默认false:    表示使用现有的scope

设置为true  :    表示新的scope(会继承父scope的属性)    

设置为{}    :    表示独立的scope(默认访问不到父scope的属性)

在设置为对象{}的时候,可以通过绑定策略传递父scope的属性

scope为true和默认false时,观察h2内容即可看到效果

  1. <body ng-app="myApp" ng-init="user='aaa'">
  2. <h2>{{user}}</h2>
  3. <span hello></span>
  4. <script>
  5. angular.module('myApp', [])
  6. .directive('hello', [function () {
  7. return {
  8. scope: true,
  9. template: '<span>Hello-{{user}}</span>',
  10. link: function ($scope) {
  11. $scope.user = 'ccc';
  12. }
  13. }
  14. }]);
  15. </script>
  16. </body>

  

我们再探索下为scope为对象的时候,在上面的例子中做下调整,使用绑定策略@

  1. <span hello="{{user}}"></span>
  2. <script>
  3. angular.module('myApp', [])
  4. .directive('hello', [function () {
  5. return {
  6. scope: {
  7. user: '@hello'
  8. },
  9. template: '<span>Hello-{{user}}</span>',
  10. link: function ($scope) {
  11. $scope.user = 'ccc';
  12. }
  13. }
  14. }]);
  15. </script>

发现和scope为false的时候效果一样,其实这已经为完全独立的scope了

我们再调整下绑定策略为=

  1. <span hello="user"></span>
  1. return {
  2. scope: {
  3. user: '=hello'
  4. },
  5. template: '<span>Hello-{{user}}</span>',
  6. link: function ($scope) {
  7. $scope.user = 'ccc';
  8. }
  9. }

最后我们看下&

  1. <body ng-app="myApp" ng-controller="helloCtrl">
  2. <span func="log(aa,bb)"></span>
  3. <script>
  4. angular.module('myApp', []).controller('helloCtrl', function ($scope) {
  5. $scope.log = function (name, age) {
  6. console.log('hello:' + name + ':' + age);
  7. }
  8. }).directive('hello', [function () {
  9. return {
  10. scope: {
  11. func: '&'
  12. },
  13. template: '<span ng-click="func({aa:\'小2\',bb:\'19岁\'})">Click Me</span>',
  14. link: function ($scope) {
  15. $scope.user = 'ccc';
  16. $scope.func({ aa: '小M', bb: '18岁' });
  17. }
  18. }
  19. }]);
  20. </script>
  21. </body>

我想到此,scope已经ok.

link

谈到link一般都会说说compile,但我这里会重点介绍controller,require

link函数      会在指令的每个实例上触发一次.

controller函数     一般用来在指令间传递数据

require函数    依赖其他的指令

我们来自定义一个'经典的'according

  1. <body ng-app="myApp" ng-init="items=[{title:'t1',text:'x1'},{title:'t2',text:'x2'},{title:'t3',text:'x3'}]">
  2. <div hello>
  3. <div word title="item.title" ng-repeat="item in items">{{item.text}}</div>
  4. </div>
  5. </body>

先定义hello 指令

  1. angular.module('myApp', [])
  2. .directive('hello', [
  3. function () {
  4. return {
  5. scope: {
  6. title: '='
  7. },
  8. transclude: true,
  9. replace: true,
  10. controller: function () {
  11. var words = [];
  12. this.add = function (word) {
  13. words.push(word);
  14. }
  15. this.openOne = function (word) {
  16. for (var i = 0; i < words.length; i++) {
  17. if (words[i] !== word)
  18. words[i].show = false;
  19. }
  20. }
  21. },
  22. template: '<div ng-transclude></div>'
  23. }
  24. }
  25. ])

word指令

  1. .directive('word', [
  2. function () {
  3. return {
  4. require: '?^hello',
  5. scope: {
  6. title: '='
  7. },
  8. transclude: true,
  9. replace: true,
  10. template: '<div><div ng-click="toggle()">{{title}}</div><div ng-show="show" ng-transclude></div></div>',
  11. link: function (scope, ele, attr, ctrl) {
  12. if (!ctrl) {
  13. console.warn('无hello指令');
  14. return;
  15. }
  16. scope.show = false;
  17. ctrl.add(scope);
  18. scope.toggle = function () {
  19. scope.show = !scope.show;
  20. ctrl.openOne(scope);
  21. }
  22. }
  23. }
  24. }
  25. ]);

效果图(这个according是不是太low了):

require

require接受字符串或字符串数组.会将对应的控制器注入到link函数的第4个参数上.

默认会在自身找的元素找指令

加^表示会从父级找指令

加?表示如果没找到,传递null给link

通常为了防止报错,会传'?^'组合(不分先后)

这里再补充下ngModel的情况.因为常常要和模型做交互

也就是require:'?ngModel'这种情况.

再补充下ngModelCtrl常用的属性或方法:

$setViewValue():  设置ngModel值

$formatters:    格式化模型显示值

$render:      定义模型如何渲染展示方法

我的指令

虽然angular已经有很多指令插件,但我还是忍不住写了一些指令.

如分页,文件上传,富文本等。

分享1个今天写的fileinput 热乎着呢。

Nuget:Install-Package angularjs.fileinput

GitHub: https://github.com/NeverCL/Angular.FileInput

同时推荐一篇很详细的博客:http://www.cnblogs.com/rohelm/p/4051437.html

本文地址:http://www.cnblogs.com/neverc/p/5916247.html

[AngularJS] AngularJS系列(4) 中级篇之指令的更多相关文章

  1. Kotlin——从无到有系列之中级篇(四):面向对象的特征与类(class)继承详解

    如果您对Kotlin很有兴趣,或者很想学好这门语言,可以关注我的掘金,或者进入我的QQ群大家一起学习.进步. 欢迎各位大佬进群共同研究.探索 QQ群号:497071402 进入正题 在前面的章节中,详 ...

  2. [AngularJS] AngularJS系列(3) 中级篇之表单验证

    目录 基本验证 验证插件messages 自定义验证 基本验证 <form name="form" novalidate ng-app> <span>{{f ...

  3. [AngularJS] AngularJS系列(6) 中级篇之ngResource

    目录 $http ngResource $http几乎是所有ng开发中,都会用到的服务.本节将重点说下$http 与 ngResource $http 使用:$http(config); 参数: me ...

  4. [AngularJS] AngularJS系列(2) 中级篇之路由

    目录 原理 angular-route ui-router 事件 深度路由 原理 ng的route本质是监听hashchange事件. 在angular-route中 $rootScope.$on(' ...

  5. [AngularJS] AngularJS系列(5) 中级篇之动画

    目录 CSS定义 JS定义 ng动画实际帮我们在状态切换的时候 添加特定的样式 从而实现动画效果. 一般我们会通过C3来实现具体的动画. CSS定义 ng-if 图(实际上,图并不能展现出什么): H ...

  6. 阿里巴巴笔试整理系列 Session2 中级篇

    1知识点储备-----2笔试题总结-----3面试经验总结 知识点储备 2014年8月29日在线笔试题:20单选(40分钟内完成)+附加题(2道编程+1道问答) 1. 通过算法生成的随机数是“伪随机” ...

  7. AngularJS入门心得3——HTML的左右手指令

    在<AngularJS入门心得1——directive和controller如何通信>我们提到“AngularJS是为了克服HTML在构建应用上的不足而设计的.HTML是一门很好的为静态文 ...

  8. Angularjs进阶笔记(2)-自定义指令中的数据绑定

    有关自定义指令的scope参数,网上很多文章都在讲这3种绑定方式实现的效果是什么,但几乎没有人讲到底怎么使用,本篇希望聊聊到底怎么用这个话题. 一. 自定义指令 自定义指令,是Angularjs用来实 ...

  9. AngularJS路由系列(6)-- UI-Router的嵌套State

    本系列探寻AngularJS的路由机制,在WebStorm下开发.本篇主要涉及UI-Route的嵌套State. 假设一个主视图上有两个部分视图,部分视图1和部分视图2,主视图对应着一个state,两 ...

随机推荐

  1. Java虚拟机13:互斥同步、锁优化及synchronized和volatile

    互斥同步 互斥同步(Mutual Exclusion & Synchronization)是常见的一种并发正确性保证手段.同步是指子啊多个线程并发访问共享数据时,保证共享数据在同一时刻只能被一 ...

  2. Java多线程12:ReentrantLock中的方法

    公平锁与非公平锁 ReentrantLock有一个很大的特点,就是可以指定锁是公平锁还是非公平锁,公平锁表示线程获取锁的顺序是按照线程排队的顺序来分配的,而非公平锁就是一种获取锁的抢占机制,是随机获得 ...

  3. Python3实现TCP端口扫描器

    本文来自 高海峰对 玄魂工作室 的投稿 作者:高海峰 QQ:543589796 在渗透测试的初步阶段通常我们都需要对攻击目标进行信息搜集,而端口扫描就是信息搜集中至关重要的一个步骤.通过端口扫描我们可 ...

  4. java提高篇(十)-----详解匿名内部类

    在java提高篇-----详解内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意的事项.如何初始 ...

  5. [php入门] 2、基础核心语法大纲

    1 前言 最近在学PHP,上节主要总结了PHP开发环境搭建<[php入门] 1.从安装开发环境环境到(庄B)做个炫酷的登陆应用>.本节主要总结PHP的核心基础语法,基本以粗轮廓写,可以算作 ...

  6. 爱上MVC3系列~开发一个站点地图(俗称面包屑)

    回到目录 原来早在webform控件时代就有了SiteMap这个东西,而进行MVC时代后,我们也希望有这样一个东西,它为我们提供了不少方便,如很方便的实现页面导航的内容修改,页面导航的样式换肤等. 我 ...

  7. Atitit dsl实现(1)------异常的库模式实现  异常的ast结构

    Atitit dsl实现(1)------异常的库模式实现  异常的ast结构 1.1. Keyword 1 1.2. 异常的ast模型 1 1.3. Astview的jar org.eclipse. ...

  8. Atitit.eclipse 4.3 4.4  4.5 4.6新特性

    Atitit intellij idea的使用总结attilax 1. ideaIC-2016.2.4.exe1 1.1. Ij vs eclipse市场份额1 1.2. Ij的优点(方便的支持gro ...

  9. 每天一个linux命令(39):grep 命令

    Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expression Print,表示全局正则表达 ...

  10. Liferay7 BPM门户开发之39: Form表单提交的ProcessAction处理

    在v6.2开始后,需要设置<requires-namespaced-parameters>false</requires-namespaced-parameters>  来避免 ...