一、首先我们来了解下指令API

属性 含义
restrict 申明标识符在模版中作为元素,属性,类,凝视或组合,怎样使用
priority 设置模版中相对于其它标识符的运行顺序
Template 指定一个字符串式的内嵌模版,假设你指定了模版是一个URL,那么是不会使用的
tempateUrl 指定URL载入的模版,假设你已经指定了内嵌的模版字符串,那么它不会使用的
Replace 假设为真,替换当前元素,假设是假或未指定,拼接到当前元素
Transclude 移动一个标识符的原始字节带你到一个新模版的位置
Scope 为这个标识符创建一个新的作用域,而不是继承父作用域
Controller 创建一个控制器通过标识符公开通信API 
Require 当前标识符须要另外一个标识符提供正确的函数功能
Link 通过代码改动目标DOM元素的实例,加入事件监听,建立数据绑定
Compile 通过标识符拷贝编程改动DOM模版

在这里,我们简单的了解下每一个属性的含义及其简单的作用,在后面我们将会通过一些励志来解释

接下来,我们来了解下指令定义对象

restrict:restrict属性同意为标识符指定声明样式,也就是说它能够作为元素名,属性,类或凝视。我们能够使用一个字符串来代表下表中的每一个标志,从而指定

一个或者多个声明样式

标志 样式 演示样例
E Element <my-menu title='products'></my-menu>
A Attribute <div my-menu='products'></div>
C Class <div class='my-menu:products'></div>
M Comment <!--directive:my-menu products-->

假设你希望标识符作为元素后者属性,你能够传递EA作为restrict的字符串

假设省略了restrict属性,默认就是A,具体请看angular文档

Priorities:为应用程序指定顺序,数值越大就越先执行,默认是为零,普通情况下无需设置优先级

Templates:在创建组件时,angular同意你在模版中替换和包装元素中的内容,假设你想创建例如以下的标签视图

不是使用一串<div><ul><li><a>等元素来实现,而是能够通过自己定义创建标识符<tab-set><tab>,分别声明每一个页签的结构,可能假设下

<tab-set>
<tab title='Home'>
<p>Welcome home!</p>
</tab>
<tab title='Preferences'>
<!-- preferences UI goes here -->
</tab>
</tabset>

同一时候,你也可通过控制器为title和页签内容进行数据绑定,并用这样的方式做出菜单,手风琴,弹窗,对话框或其它应用需求

接下来,让我们来看看temp拉特或者templateUrl属性,指定替换DOM元素。在上表中,我们看到template能够用来设置模版内容的字符串,

templateUrl用于指定将被载入的server文件,正如接下来看到的演示样例,我们能够预缓存这些模版,一遍降低get请求数,提高性能

<html lang='en' ng-app='app'>
...
<body>
<hello></hello>
</body>
...

创建<hello></hello>标签替换<div>hi there</div>,replace设置为true同意拼接内容到元素上,设置replace成为true

var appModule = angular.module('app', []);
appModule.directive('hello', function() {
return {
restrict: 'E',
template: '<div>Hi there</div>', replace: true
};
});

在载入到浏览器后,我们会看到hi there,通过查看页面源代码,我们还是会看到<hello></hello>可是假设你检查生成代码(chrome,右击hi htere,选择检查元素)你会看到

<body>
<div>Hi there</div>
</body>

<hello></hello>已经被模版中的<div>替换。

而相对于使用template 输入html到字符串中不是非常有意义,一般我们都会使用templateUrl,进行设置适当的头部缓存

var appModule = angular.module('app', []);
appModule.directive('hello', function() {
return {
restrict: 'E',
templateUrl: 'helloTemplate.html', replace: true
};
});

在helloTemplate.html中,我们须要写入

<div> Hi there</div>

假设你使用chrome浏览器,同源策略会组织可能会导致遇到一个错误“Origin null is not allowed by Access-Controll-Allow-Origin”.这里你有两种可选方式

1.通过server载入应用

2.chrome 中设置一个标志,通过命令行‘chrome-allow-file-access-from-files’解决

然后通过templateUrl载入文件,会使用户等待知道载入后看到标识符,假设你希望第一次页面载入时就载入模版,你能够在script标签中让其作为页面的一部分,例如以下

<script type='text/ng-template' id='helloTemplateInline.html'>
<div>Hi there</div>
</script>

这里的id属性很重要,由于是URL键,angular用它来存储模版,你应该在标识符的templateUrl中使用id来指定插入那个模版

还有我们能够通过$http或其它几种机制载入模版,然后直接设置到angular所使用的$templateCache对象中,并可通过run函数调用它,使其在标识符执行之前让这个模版在

缓存中可用

var appModule = angular.module('app', []);
appModule.run(function($templateCache) {
$templateCache.put('helloTemplateCached.html', '<div>Hi there</div>');
});
appModule.directive('hello', function() {
return {
restrict: 'E',
templateUrl: 'helloTemplateCached.html', replace: true
};
});

Transclusion(嵌入包括)

通过transclude属性移动原始的内容到新模版中,当设置成为true时,标识符会删除原来的内容,并通过ng-transclude标识符使它又一次插入到模版中

採用transclusion方式改动演示样例:

appModule.directive('hello', function() {
return {
template: '<div>Hi there <span ng-transclude></span></div>', transclude: true
};
});

应用在:

<div hello>Bob</div>

我们会看到‘Hi there Bob.’

编译和链接函数

尽管插入模版是实用,可是在不论什么标识符真正有意义的工作发生在编译活着链接功能里

编译和链接的功能就是angular为引用创建实时视图的后两阶段,让我们来看下angular初始化过程的高层次视图,依照次序

【1】脚本载入:载入angular,查找ng-app标识符找到应用绑定

【2】编译阶段:在这一阶段,angular便利DOM标志模版中全部注冊的标志,对于每一个标识符,基于标识符规则(template,replace,transclude等等)改造DOM,然后

假设编译函数存在就调用它,结果一个编译的template函数,它会调用全部的标识符搜集的link韩素

【3】链接阶段:为了让视图动起来,angular为每一个标识符执行link函数,link函数通常在DOM或模型上创建监听器,这些监听器让视图和模型始终保持一致

因此到了编译阶段,它处理转换了模版,链接阶段,它处理了改动视图中的数据,沿着这些思路,标识符中表一功能和链接功能主要差别就是链接功能转换了模版自身,而连接功能在模型和视图上创建了动态链接,就是在第二阶段,作用域scpoes被附加到了编译过程的link功能上,通过数据绑定,标识符变活了

二、作用域

获取作用域scope的三种选择

1.标识符DOM元素中已经存在的作用域

2,创建一个继承封闭的控制器作用域的新作用域,以便读取结构树作用域的全部值。

3.独立作用于,从父类中不继承不论什么属性,当你须要隔离这个标识符的操作和父类作用域时,创建可从用的组建来使用这个选项

我们能够用例如以下语法类创建这些作用域配置

已有作用域 scope:false(假设没有指定,这就是默认值)
新作用域 scope:true
独立作用域 scope:{属性名次和绑定风格}

当你创建一个独立作用域时,默认情况下不能訪问父类作用域的模型,但我们能够通过指定须要的属性传递到标识符

注意:尽管独立作用域并没有继承模型属性,但他们仍然是父作用域的子节点,并$parent指向父类

我们能够通过标识符属性的键值对父类传递指定的属性给独立作用域,这里有三种可行的方式从父作用域传递数据,我们称这些传递数据方式叫做“绑定策略”,你能够为这个属性名称指定一个本地别名

没有别名的语法例如以下:

scope: { attributeName1: 'BINDING_STRATEGY',
attributeName2: 'BINDING_STRATEGY', …
}

用别名的格式例如以下:

scope: { attributeAlias: 'BINDING_STRATEGY' + 'templateAttributeName',

}
符号 意义
@ 传递字符串属性,你能够通过使用改写{{}}属性值从粉笔作用域中进行数据绑定
= 数据绑定属性在标识符父作用域的属性中
& 传递一个来自父作用域的函数,稍后调用

在这我们用一个详细样例上的变化来说明它们,比方我们想创建一个expander标识符,展示一个标题栏,当点击时扩展显示额外内容

关闭的时候

打开的状态

代码例如以下:

<div ng-controller='SomeController'>
<expander class='expander' expander-title='title'>
{{text}}
</expander>
</div>

控制器代码:

function SomeController($scope) {
$scope.title = 'Click me to expand';
$scope.text = 'Hi there folks, I am the content
+ 'that was hidden but is now shown.';
}

然后我们编写标识符

angular.module('expanderModule', [])
.directive('expander', function(){
return {
restrict: 'EA', replace: true,
transclude: true,
scope: { title:'=expanderTitle' }, template: '<div>' +
'<div class="title" ng-click="toggle()">{{title}}</div>' +
'<div class="body" ng-show="showMe" ng-transclude></div>' +
'</div>',
link: function(scope, element, attrs) {
scope.showMe = false;
scope.toggle = function toggle() {
scope.showMe = !scope.showMe;
}
}
}
});

样式:

.expander {
border: 1px solid black;
width: 250px;
}
.expander > .title {
background-color: black;
color: white; padding: .1em .3em; cursor: pointer;
}
.expander > .body {
padding: .1em .3em;
}

元素的功能

功能名  
Restrict:EA 描写叙述调用标识符为元素或属性,也就是<expander>..</expander>或

<div expander>...</div>
Replace:true 用提供的模版替换原来的元素
Transclude:true 移动原始元素内容到提供的模版中的另外一个地方
Scope:{title:=expanderTitle}} 创建一个叫title的本地作用域属性,它是用来数据绑定到expander-title

属性中声明的parent-scope属性,这里,为了方便expanderTitle冲命名

为title,因为expanderTitle在模版中,我们飙血作用域

scope:{expanderTitle:'='}来引用它,但在这个场景中,其它标识符也

有一个title属性,为了防止引起歧义,我们将其重命名
Template:<div>+ 为标识符提供即将插入的模版,注意,我们使用ng-click和ng-show

来展示或隐藏自身,ng-transclude来申明原始的内容将何去何从,

同一时候注意嵌入的内容能够訪问父作用域,而不是封闭标识符的

作用域
Link: 建立showMe模型,跟踪expander的打开和关闭状态,然后当用户点击title 

div时,调用定义的toggle函数

三、操作DOM元素

函数 描写叙述
Controller(name) 与控制器直接进行通信,这个函数返回绑定在元素上的控制器

假设这个元素不存在,它会遍历DOM,然后查找近期的父控制

器取代,假设參数名字是可选的,用于指定允许元素上其它

标识符名称,假设提供了,则返回标识符上的控制器,这个名字

应该使用驼峰式,也就是说用ngModel取代ng-model
Injector() 获取当前元素或者父元素的注入器,同意在这些模块中查找依赖
Scope() 返回当前元素或者近期父元素的作用域
inHeritedData() 和jquery的data()函数一样,inheritedData()以封闭的方式设置以及获取元素上的

数据,除了从当前元素获取数据,它会便利DOM查找

以下样例,我们不用ng-show和ng-click又一次实现之前expander演示样例

angular.module('expanderModule', [])
.directive('expander', function(){
return {
restrict: 'EA', replace: true, transclude: true,
scope: { title:'=expanderTitle' }, template: '<div>' +
'<div class="title">{{title}}</div>' +
'<div class="body closed" ng-transclude></div>' +
'</div>',
link: function(scope, element, attrs) {
var titleElement = angular.element(element.children().eq(0));
var bodyElement = angular.element(element.children().eq(1));
titleElement.bind('click', toggle);
function toggle() {
bodyElement.toggleClass('closed');
}
}
}
});

在上面我们从模版中移除了ng-click和ng-show标识符,然而,当用户点击expander标题时候,仍然运行预期的操作,我们从tittle元素上创建了一个jqLite元素,然后把toggle函数绑定到click事件上作为它的回调,在toggle函数,我们在expander body元素上调用toggleClass()

来加入或移除closed的类,我们会设置这个元素class设置成的displat:none

.closed {
display: none;
}

angularjs入门学习【指令篇】的更多相关文章

  1. Sublime text 入门学习资源篇及其基本使用方法

    Sublime text 学习资源篇 史上最性感的编辑器-sublimetext,插件, 学习资源 官网 http://www.sublimetext.com/ 插件 https://packagec ...

  2. AngularJS 基础入门(指令篇)

    一.介绍 AngularJS 是google 开发人员设计的一个前端开发框架,它是由是由javascript 编写的一个JS框架.通常它是用来在静态网页构建动态应用不足而设计的. AngularJS特 ...

  3. Angularjs入门学习一 简介

    本系列文章是从头开始学习angularjs,下文中用ng表示angularjs,要知道从以为根深蒂固的jquery开发者转变开发思想,确实需要一段时间,下面介绍以下 angularjs,我也是参考网上 ...

  4. angularjs入门学习【应用剖析中篇】

    在上一节讲完了关于应用开发中如数据绑定,加入样式一类的基础操作后,接下来,将在应用中,与控制其有关的一些事件... 一.UI和控制器的分离 我们须要明白控制器在应用中的三个作用: [1]在应用模型中设 ...

  5. AngularJS入门学习

    初识: {{}}   这种双层花括号的语法称之为:插值语法:也可以说是 标识符:AngularJS 主要就是使用这种方法进行数据绑定 ng-module="name"   在ng的 ...

  6. cocos2d-x入门学习--准备篇

    1.Cocos2D最早是一款用Python语言开发的游戏引擎.Cocos2D是一个开源框架,用于构建二维游戏,演示程序和其他图形界面交互应用等. 2.x的包含两个意思:一方面是C++的文件扩展为CXX ...

  7. LAUNCHXL-28379D入门学习-第一篇

    1. 首先安装controlSUITE或者C2000ware软件,TI官网下载,安装后包括C2000的函数库和例程之类的,还可以和CCS搭配使用.controlSUITE安装完之后大约4个G,所以我安 ...

  8. VHDL语法入门学习第一篇

    1. 现在先遇到一个VHDL的语法问题,以前没用过VHDL,现在要去研究下,进程(PROCESS) 进程内部经常使用IF,WAIT,CASE或LOOP语句.PROCESS具有敏感信号列表(sensit ...

  9. 跟我学AngularJs:AngularJs入门及第一个实例

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:主要给大家介绍了AngularJs及其特性,并以3个实例来做说明. 本教程使用Angul ...

随机推荐

  1. badi增强

    对于根据事务代码查找对应的BADI,网上介绍的方法很多,但总结下来无非就两种方法,在此把它记录下来,方便以后自己查阅了. (1)通过SE24,输入CL_EXITHANDLER,然后在方法GET_INS ...

  2. 与众不同 windows phone (12) - Background Task(后台任务)之 PeriodicTask(周期任务)和 ResourceIntensiveTask(资源密集型任务)

    原文:与众不同 windows phone (12) - Background Task(后台任务)之 PeriodicTask(周期任务)和 ResourceIntensiveTask(资源密集型任 ...

  3. Linux Shell常用技巧(二) grep

    七. grep家族:       1.  grep退出状态:    0: 表示成功:    1: 表示在所提供的文件无法找到匹配的pattern:    2: 表示参数中提供的文件不存在.    见如 ...

  4. HDU 1254 推箱子游戏(搞了一下午。。。)

    中文题目:http://acm.hdu.edu.cn/showproblem.php?pid=1254 一开始常规的人用来做主导,想着想着不对劲,其实是箱子为主导,人只是箱子能否推进的一个判断. 可以 ...

  5. 高效 Java Web 开发框架 JessMA v3.2.3 beta-1 发布

    JessMA(原名:Portal-Basic)是一套功能完备的高性能 Full-Stack Web 应用开发框架,内置可扩展的 MVC Web 基础架构和 DAO 数据库访问组件(内部已提供了 Hib ...

  6. 轻松学会多线程(四)——synchronized同步keyword知多少

    每个对象都有一把独占锁. 独占锁仅仅限制线程对它的同步方法的訪问,对非同步方法,独占锁没有意义. synchronizedkeyword能够作为函数的修饰符,也能够作为函数内的语句,也就是平时说的同步 ...

  7. 【总结】在VirtualBox上面安装Mac的注意事项

    看此文之前 http://www.crifan.com/category/work_and_job/virtual_machine/virtualbox-virtual_machine/ 此文仅仅是针 ...

  8. 《sql---教学反馈系统-阶段项目1》

    --修改列 --把 "Address" 栏位改名为 "Addr".这可以用以下的指令达成: --ALTER table customer change Addr ...

  9. 慕尼黑大学公开课 Competitive Strategy(竞争策略)总结

    第一章博弈 同时的博弈:双方同时定制策略 如果有显著的次优策略总是不如另一个,则剔除它. 如果一个策略组合中没有一方可以单独改变其策略以提高回报,则称为Nash均衡.一个游戏可能没有也可能有多个Nas ...

  10. Git中的merge命令实现和工作方式

    想象一下有例如以下情形:代码库中存在两个分支,而且每一个分支都进行了改动.最后你想要将当中的一个分支合并到其它的分支中.个人博客网址 http://swinghu.github.com/ 那么要问合并 ...