学习笔记-AngularJs(十)

前面一直在说自定义指令,但是却一直没有一次系统地去了解,现在需要我们一起来学习如何去使用自定义指令,去丰富html标签、属性,实现多元化、多功能的标签(或是属性)。辣么,啥是指令?要了解指令,首先需要了解AngularJs的HTML编译器,简单地说让浏览器认识你自定义指令或是Angular的指令集,将其行为运用到DOM上(视图),分两个过程编译和链接,编译阶段是遍历DOM并且收集所有的相关指令,生成一个链接函数;链接阶段是给通过编译阶段调用所说的链接函数来将模板与作用域链接起来,绑定一个作用域,生成一个动态的视图。作用域模型的任何改变都会反映到视图上,并且视图上的任何用户操作也都会反映到作用域模型。

那么说到底,由某个属性、元素名称、css类名出现而导致的行为,或者说是DOM的变化,能让你以一种声明式的方法来扩展HTML表示能力,这就是指令!

官网(忽略,http://t.cn/RUbL4rP)也写了一个比较详细的指令demo(具体属性分析如下):

var myModule = angular.module(...);
myModule.directive('directiveName', function factory(injectables) { //工厂函数里面injectables是何意呢?望知道的人告知
var directiveDefinitionObject = {
priority:
0, //优先级priority,Dom里面会有很多指令,定义优先级,可以使此指令优先执行
terminal:false, //如果被设置为true,那么该指令就会在同一个DOM的指令集和中最后被执行
template: '<div></div>', // or // function(tElement, tAttrs) { ... }, // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... }, //template或templateUrl顾名思义就是模板文件,可以编写,也可以url,也可以是function(tElement,tAttrs){ return ... ;}

replace: false, //是否替换现在的元素

transclude: false, //重要属性之一,配合ng-transclude使用,为true时,可以将原元素的内容(html、其他指令)提取到带有指令ngTransclude的元素内,下面有例子说明!(注:指令的内部可以访问外部指令的作用域,并且模板也可以访问外部的作用域对象

restrict: 'A', //以哪种形式声明指令行为的格式,有AECM,分别是属性<div my-directive="exp"> </div> 、元素*<my-directive></my-directive> 、 class*<div class="my-directive: exp;"></div> 、注释<!-- directive: my-directive exp -->

templateNamespace: 'html', //模板的命名空间,有'html'、'svg'等,默认为'html'

scope: false, //是否创造一个新的作用域(针对指令)
     /*scope是最难理解的一个属性*/

controller: function($scope, $element, $attrs, $transclude, otherInjectables) {... }, //控制器的构造对象,预编译阶段执行,$scope当前作用域,$element当前元素,$attrs当前元素的属性集合,并且它是共享的,其他指令可以通过它的名字得到(参考依赖属性(通过require属性引入)。这就使得指令间可以互相交流来扩大自己的能力。当然也可以是控制        器名字(那么此控制器需要在应用声明好,这样便可以通过注入$attrs、$element操纵指令对应模板的dom),$transclude,用来操作嵌入作用域对应的dom,也就是被提取到ngTransclude的元素里面的dom了,下面有例子说明!

controllerAs: 'stringAlias', //定义控制器的别名

require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'], // 请求将另一个控制器作为参数传入到当前链接函数。 这个请求需要传递被请求指令的控制器的名字。之前有例子关于表单自定义                        验证有使用到,学习笔记-AngularJs(八)

compile: function compile(tElement, tAttrs, transclude) { //tElement指令所在的元素,tAttrs指令所在元素属性集合 return { pre: function preLink(scope, iElement, iAttrs, controller) {... }, post: function postLink(scope, iElement, iAttrs, controller) {... } } // or // return function postLink( ... ) { ... } //编译函数是用来处理需要修改模板DOM(执行于放到dom之前的dom操作)的情况的。因为大部分指令都不需要修改模板,所以这个函数也不常用。返回的是函数或是对象,返回函数时等效于link链接函数 }, // or // link: { //链接函数负责注册DOM事件和更新DOM。它是在模板被克隆之后执行的。 它也是大部分指令逻辑代码编写的地方。scope当前作用域,iElement当前元素,iAttrs当前元素的属性集合,controller就是上面require属性的值,于是就可以调用require进来的控制            器的属性方法,(包括之前讲的ngModel或是其他指令controller和controllerAs定义的有控制器名的控制器方法) // pre: function preLink(scope, iElement, iAttrs, controller) { ... }, // post: function postLink(scope, iElement, iAttrs, controller) { ... } // } // or // link: function postLink( ... ) { ... } }; return directiveDefinitionObject; });

 compile和link选项是互斥的。如果同时设置了这两个选项,那么会把compile所返回的函数当作链接函数,而link选项本身则会被忽略。

编译函数负责对模板DOM进行转换。链接函数负责将作用域和DOM进行链接。

上面demo有些属性在实际操作上,都是取默认的属性,那么官网将其简化成了这个样子:

var myModule = angular.module(...);
myModule.directive('directiveName', function factory(injectables) { //此处需要注意,在视图引入指令时,采用的是骆峰命名法,所以调用时应该是directive-name
var directiveDefinitionObject = {
link: function postLink(scope, iElement, iAttrs) { ... }
};
return directiveDefinitionObject;
// or
// return function postLink(scope, iElement, iAttrs) { ... }
});
View Code

到这里还是需要编写些demo,才能起到学习的效果!

在之前的学习笔记-AngularJs(八)里面就有一个自定义表单验证的demo,情景是这样的,在input框里面不能写入“xiaobin”,主要是对ngModel中$setValidity(validationErrorKey, isValid);$setViewValue(value, trigger);在双向绑定中是如何实现scope->view、view->scope之间的那个验证和格式化的学习,没看过的话,可以去看一下,虽然理解得不透彻!下面贴一下主要代码:

var custom = angular.module('customControl', ['ngSanitize']);
custom.directive("noxiaobin", function () {
return {
restrict: "A",
require: "?ngModel",
link: function (scope, element, attrs, ngModel) {
if (!ngModel) return;
ngModel.$parsers.push(function (v) { //传说中的验证器
if (v != "xiaobin") {
ngModel.$setValidity('noxiaobin', true); //通过获取从dom过来的值,然后进行验证,使用$setValidity('noxiaobin', true);改变noxiaobin的值,然后反馈会dom
return v;
} else {
ngModel.$setValidity('noxiaobin', false);
return undefined;
}
});
}
}
});
View Code

在这里,我们另外写一个比较综合的例子,dialog.html可到github下载(github地址:https://github.com/xiaobin5201314/AngularJS-Learning/tree/master/block-example/指令-13)

<!doctype html>
<html ng-app='directiveModule'>
<head>
<meta charset="utf8"/>
<script src="../jquery.js"></script>
<script src="../angular.js"></script>
<script src="../bootstrap.min.js"></script>
<link rel="stylesheet" href="../bootstrap.min.css">
<script>
var directive = angular.module('directiveModule', []);
//这里是验证指令的内部可以访问外部指令的作用域,这样我们在dialog.html也可以查看到遍历出来的的arrs
directive.controller("directiveControl",["$scope",function($scope){
$scope.arrs=["我是内容一","我是内容二","我是内容三"];
$scope.hide=false;
}])
//将任意可以被注入的ng服务注入到控制器中,便可以在指令中使用它了。控制器中也有一些特殊的服务可以被注入到指令当中,当然这是在应用上声明、也可以直接写在controller属性上
directive.controller("directiveChildControl",['$scope','$attrs','$element','$transclude',function($scope,$attrs,$element,$transclude){
$element.css('border', '#fff');             //改变模板dom里面的结构
$transclude(function (clone) {              //这是操作嵌入的作用域里面的dom
var a = angular.element('<a>');
a.attr('href', 'http://www.cnblogs.com/wuxiaobin');
a.text('我的博客原地址');
$element.find('.modal-body').append(a);
});
}])
directive.directive("dialog", function () {
return {
restrict: "AE",
replace: true,
transclude:true, //配合ng-transclude使用,为true时,可以将原元素的内容(html、其他指令)提取到带有指令ngTransclude的元素内
controller:'directiveChildControl',
scope:{
title:"@" //模板也可以访问外部的作用域对象,dialog.html的{{title}}正是局部作用域访问父作用域的所产生的效果,这样可以很好实现我们的组件的设计思想,但对于@、=、&的写法有些不理解,望有更好的学习资料可以提供一下,当然搞懂了,也会更新上来
                     },
templateUrl: 'dialog.html',
link: function(scope, element, attrs, ctrl) { 
console.log(element.html());
element.find('.modal-title').css('color', 'red'); 
}
}
});
</script>
</head>
<body ng-controller="directiveControl">    
<button class="btn btn-lg btn-primary " data-toggle="modal" data-target="#myModal">弹出模态框</button>
<dialog title="我是传递过来的title">
<span ng-repeat="arr in arrs" ng-hide="hide">
{{$index}}-{{arr}} <br>
</span>
我的内容即将保存,被提取到<code>  span[ng-transclude] </code></dialog>
</body>
</html>

效果图:


更多专业前端知识,请上 【猿2048】www.mk2048.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361925.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WildFly 9 –别希望您的控制台像这样!

每个人都可能听到这个消息。 周一发布了第一个WildFly 9.0.0.Alpha1版本。 您可以从wildfly.org网站上下载它&#xff0c;最大的变化是它是由一个新的功能配置工具构建的&#xff0c;该工具位于现在单独的核心发行版中&#xff0c;并且还包含一个新的Servlet发行版 &#xff08…

磁盘性能 -- IOPS 和 吞吐量 说明

一. Wikepedia上有关IOPS 的说明链接如下&#xff1a;http://en.wikipedia.org/wiki/IOPSIOPS (Input/Output OperationsPer Second, pronounced i-ops) is a common performance measurement used to benchmark computer storage devices like harddisk drives (HDD), solid s…

webpack联邦模块之webpack运行时

webpack是如何打包ES模块的&#xff1f;webpack是如何构建自身的模块运行时的&#xff1f; __webpack_require__ 这是整个webpack运行时的核心。 该函数被用于根据模块Id从变量__webpack_module_cache__获取模块对应导出&#xff1a; 有&#xff0c;直接返回没有&#xff0…

学习笔记-AngularJs(四)

之前学习的事视图与模版&#xff0c;我们在控制器文件中直接定义一个数组&#xff0c;让其在模版文件中用ng-repeat指令构造一个迭代器&#xff0c;定义的数组http://t.cn/RUbL4rP如同以下&#xff1a; $scope.phones [{name:xioabin,number:18824863682,age:12},{name:xioalo…

3使用Jsoup解析Java中HTML文件的示例

HTML是Web的核心&#xff0c;无论您是通过JavaScript&#xff0c;JSP&#xff0c;PHP&#xff0c;ASP还是任何其他Web技术动态生成的&#xff0c;您在Internet上看到的所有页面都是基于HTML的。 您的浏览器实际上是解析HTML并为您呈现。 但是&#xff0c;如果需要解析HTML文档并…

转载:闲话权限设计三层境界

转自&#xff1a;http://www.cnblogs.com/tsoukw/archive/2010/09/27/1836485.html喜欢金庸的武侠&#xff0c;对他那几部小说也是乐此不疲拿独孤求败来说&#xff0c;他的剑&#xff0c;从无名利剑&#xff0c;玄铁重剑&#xff0c;到木剑乃至最后的无剑&#xff0c;不知道破世…

webpack联邦模块之remotes方法

使用联邦模块后当前项目就会有两个依赖&#xff0c;一个是依赖共享模块&#xff0c;一个是依赖远程模块。运行时webpack/runtime/consumes用于解析共享模块&#xff0c;运行时webpack/runtime/remotes 用于解析远程模块。这两个模块对应的方法分别是__webpack_require__.f.cons…

径向菜单的制作

最终效果&#xff1a; 在径向菜单的制作前&#xff0c;首先需要知道几点知识点&#xff1a; Math.sin(x) x 的正玄值。返回值在 -1.0 到 1.0 之间&#xff1b; Math.cos(x) x 的余弦值。返回的是 -1.0 到 1.0 之间的数&#xff1b; 这两个函数中的X 都是指的“弧度”…

吉首大学2019年程序设计竞赛-F 天花乱坠

题目链接&#xff1a;https://ac.nowcoder.com/acm/contest/992/F 题意&#xff1a;给定正n边形&#xff0c;边长为100&#xff0c;以每条边的中点连线构成新的正n边形&#xff0c;无限循环下去&#xff0c;求所有边的长度和。 思路&#xff1a;简单数学计算题&#xff0c;可以…

SqliteHelper整理

刚开通博客不久&#xff0c;还没有发过文。这是第一篇&#xff0c;要鼓励我自己再接再厉。 另外&#xff0c;我也是刚刚踏上程序员这条路&#xff0c;有赖各位多多提携&#xff01; 闲话不多说&#xff0c;最近参与的项目包含本地化存储这一块。昨天就园子里找了些资料有另外补…

webpack联邦模块之consumes方法

对于使用联邦模块的项目会有两个依赖&#xff0c;一个是远程模块&#xff0c;一个是共享模块。上一篇文章解释了远程模块的加载和安装并初始化共享作用域。consumes则是共享模块的解决方案&#xff0c;用于在运行时加载并安装依赖的共享模块。 为什么叫consumes&#xff1f;我…

vue-cli使用说明

一、安装npm install -g vue-cli 推荐使用国内镜像 先设置cnpm npm install -g cnpm --registryhttps://registry.npm.taobao.org 如果安装失败&#xff0c;可以使用 npm cache clean 清理缓存&#xff0c;然后再重新安装 然后使用 cnpm 安装 vue-cli 和 webpack cnpm inst…

OptaPlanner –具有真实道路距离的车辆路线

在现实世界中&#xff0c;车辆路径问题&#xff08;VRP&#xff09;中的车辆必须走这条路&#xff1a;它们不能在客户之间直线行驶。 大多数VRP研究论文和演示都乐于忽略此实现细节。 和我一样&#xff0c;过去。 尽管使用道路距离&#xff08;而不是空中距离&#xff09;不会对…

自旋锁

什么是自旋锁&#xff1f; 自旋锁&#xff08;spinlock&#xff09;&#xff1a;是指当一个线程在获取锁的时候&#xff0c;如果锁已经被其它线程获取&#xff0c;那么该线程将循环等待&#xff0c;然后不断的判断锁是否能够被成功获取&#xff0c;直到获取到锁才会退出循环。 …

关于如何在PSA众多请求号中查找数据是属于哪一条。

其中有两个TCODE: RSTSODS与RSTSODS&#xff0c;我们可以查找数据源的PSA表&#xff0c;然后在SE16中可以看到。 另外我们对PSA点击管理&#xff0c;一般会出现在窗口上面出现PSA的表名。 当然有些不在的话&#xff0c;那就去查找那两个TCODE。转载于:https://www.cnblogs.com/…

TCP握手为什么需要三次通信

TCP三步握手three way (or three message) handshake 是TCP核心知识点&#xff0c;很长一段时间内我无法理解为什么TCP建立连接需要三次通信&#xff0c;而不是两次或者四次或者更多次。我翻了很多问答和博客&#xff0c;他们说的都很有道理&#xff0c;但是借来的火&#xff0…

小程序用户拒绝授权解决方法

众所周知&#xff0c;小程序进入首先都要进行微信授权的&#xff0c;那万一用户不小心点了拒绝按钮怎么办呢&#xff1f;不要慌&#xff0c;官方早已预料到此情况&#xff0c;并提供了api供开发者使用&#xff0c;下面就一起来研究下api吧 一、API接口 wx.openSetting(OBJECT)…

揭示垃圾收集暂停的时间长度

有几种方法可以改善您的产品。 一种方法是仔细跟踪用户的体验并在此基础上进行改进。 我们确实自己应用了此技术&#xff0c;并再次花了一些时间查看不同的数据 除了我们追求的许多其他方面之外&#xff0c;我们还提出了一个问题“延迟GC触发应用程序的最坏情况是什么”。 为了…

异步导致UI句柄增加的解决办法

在很多操作中&#xff0c;都会使用到异步线程&#xff0c;具体怎样使用在这不说了&#xff0c;网上有很好的说明&#xff1b;本人通过Delegate.BeginInvoke实现异步调用&#xff0c;完成后对UI控件进行设值等&#xff0c;还有System.Timers.Timer都一样&#xff0c;使用的是线程…

[转]android ListView详解

本文转自&#xff1a;http://www.cnblogs.com/allin/archive/2010/05/11/1732200.html 由于google doc 很多人都打不开&#xff0c;故更新了源码下载地址 【源码下载】----2011-01-18 在android开发中ListView是比较常用的组件&#xff0c;它以列表的形式展示具体内容&#xff…