# angularjs **Repository Path**: tHero/angularjs ## Basic Information - **Project Name**: angularjs - **Description**: 学习angularjs内容 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2016-05-23 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### angualr js 视频学习内容 #### dot 的重要 代码示例: > 在`html`页面中,定义了3个输入框,每一个输入框对应这个一个输出; index.html ```html

{{data.message}}

{{data.message}}

{{data.message}}

``` javascript内容 ```javascript function FirstCtrl($scope) { } function SecondCtrl($scope){ } ``` ![](../images/2.gif) 代码总结 --- * 在上述的`HTML`页面中,使用了`ng-model`用来映射对象,名称都一致;通过运行代码可以发现,修改任意的 input内容页面的值都会随着更改,由此可知,`使用data.messsage定义的模型,他们的作用域是相同的` 进阶 --- > 现在我们将上面的`html`代码修改一下,不在使用`data.message`的方式,将所有的`data.message`修改 为message,那么在执行命令 ```html

{{message}}

{{message}}

{{message}}

``` ![演示](../images/11.gif) 代码总结 --- * 当`FirstCtrl`和`SecondCtrl`的值没有输入时,仅输入第一个表单`input`内容,下面2个输入框将会随着 第一个表单的值变化而变化 * 当`FirstCtrl`和`SecondCtrl`的值开始输入时,对应的`h1`的内容将会改变,但是在修改input表单1时, 下面的两个表单将不会随着改变; 总结: > 在同一个`ng-app`中`message`是个全局变量,在`controller`没有该属性的时候,会向上查找, `message`属于全局变量,将会查找到该对象;同一个`controller`定义的属性只能被对应的controller引用, 其他`controller`不能相互访问 * 当`Firstctrl`与`SecondCtrl`对应的`model`被实例化后(即:`message`),就成为了他们私有的属性外界将 不允许被访问 ### angularjs 两个controller如何传递参数 在两个controller中如何进行参数的传递?一般通过注册服务,通过服务对象,来存储数据代码示例: > `html` 定义两个`controler`用于调用在`js`中定义的`controller` ```html
``` > controller 传递参数问题 ``` var myApp = angular.module('myApp',[]); myApp.factory('userData',[function () { var data = { userame:'123' } return data; }]); myApp.controller('FirstCtrl',['userData','$scope',function(userData,$scope){ userData = { username:'23' } console.log("First输出内容"); console.log(userData); }]); myApp.controller('SecCtrl',['userData',function (userData) { console.log("SecCtrl 输出内容"); console.log(userData); }]); ``` **代码说明** ``` myApp.factory('userData',[function () { var data = { userame:'123' } return data; }]); ``` 注册一个服务,`userData`表示定义对象的名称,通过该对象可以在各个controller之间进行传递参数,通过该对象,其他controller 也可以修改该值,格式如下; `app.factory('对象名称',[function(){ //代码内容 }]);`定义这样的对象时需要有返回值;即含有`return`语句 controller 如何引用定义的对象,通过注入的方式来完成,在下方通过`['userData',function(userData){}]`来完成对象的 注入,在`contoller`中是可以修改`userData`中的值的,但是仅对该作用域有效; ``` myApp.controller('SecCtrl',['userData',function (userData) { console.log("SecCtrl 输出内容"); console.log(userData); }]); ``` ![页面输出内容](WebContent/images/7.jpg) **?如何修改定义`factory`定义的全局变量** 遗留 ### 在`controller`中定义`functon` 通过$scope来绑定参数,在{{}}中定义方法,并传递`message`的对象,controller便可以进行修改内容 ```html

{{reversedMessage(message)}}

``` 也没传递的参数可以直接通过$scope.message来获得,需要注意的时候,使用split方法时需要将该对象进行初始化 ```javascript myApp.controller('ThrCtrl',['$scope',function ($scope) { $scope.message = ""; $scope.reversedMessage = function (message) { return $scope.message.split("").reverse().join(""); } }]); ``` ![controller定义function并展示](WebContent/images/8.gif) 从上述图中可以看出随着字符的输入,输出部分会逆向输出内容 ### 通过`filter`来控制字符串的倒序输出 `filter`的是使用方法:通过调用`{{message|filter方法名称}}`来完成字符串的倒序输出,需要注意的是,filter调用的方法 名称是不需要传递参数,同时也不需要含有`()` ```html

{{message|revers}}

``` `filter`定义的方法`app.filter('方法名称',function)` 调用该方法必须含有相应的返回值,一次来达到页面的输出 ```javascript //定义filter myApp.filter('revers',function(){ return function(text){ return text.split("").reverse().join(""); } }) ``` 运行方式 ![](WebContent/images/9.gif) 需求,通过在表单输入input内容来过滤表格中的值; `ng-model`定义要过滤的对象,在`filter`中来过滤要输入的内容 * 如果`ng-model`定义要查询的对象`A`(search),那么`filter`中定义的A对象与`ng-model`一致(search),那么表格中的内容将会全部进行过滤(name和character) * 如果`ng-model`定义要查询的内容`A.a` (search.name),那么`filter`过滤时只会过滤出`a`中字段(names); * 如果`ng-model`定义要查询的内容`A.$`,那么`filter`过滤时将会过滤所有内容 ### filter 内容 ```html
{{avenger.name}} {{avenger.character}}
``` 定义`javascript`的时候需要注意,想在也没使用`controller`定义的对象,需要在`controller`定义 ```javascript var myApp = angular.module('myApp',[]); myApp.factory('avenger',function () { var avengers = {}; avengers.cast = [{ name:'Robert Down', character:'Tony Task' },{ name:'chris', character:'stevent' },{ name:'mark Down', character:'Bruce Task' },{ name:'Scaret', character:'Natsa' },{ name:'Robert Down', character:'Tony Task' }] return avengers; }) myApp.controller('avenger',['avenger','$scope',function (avenger,$scope) { $scope.avengers = avenger; }]); ``` ![过滤内容](WebContent/images/10.jpg) ### `scope`相关问题 注意几个问题; * 1、 `angularjs` 提供了`ng-click`来对`dom`元素添加绑定事件; * 2、 `ng-click` 是可以直接调用定义在`controller`中的函数的;可以传递参数; 也可以传递`model`对象; * 3、 绑定到`input`表单上的`model`对象是个字符串;不能够直接进行加减;在计算时 会当成字符串进行拼接输出; ``` 例如: 并在: controller: $scop.counter += amount;

计算结果:{{counter}}

流程: input 输入1 计算结果输出的为01; ``` * 4、 在`contoller`中可以定义属性;譬如 `$scope.counter = 0` ; 同时可以定义函数,譬如: ``` $scope.add = function(amount){ $scope.counter += amount; } 有意思的是,在html中,不用添加$scope就可以访问到属性已经方法; ``` * 5、`javascript` 在操作的时候可以使用对象的方式来创建对象;并在`html`页面中 显示 ```html //在controller中定义一个对象 $scope.person = { name:"thero", age :12 } //再页面直接使用对象【.】属性的方式,就可以展示用户的信息了 用户姓名{{person.name}} 用户年龄{{person.age}} ``` ### `scope`的继承关系 > `scope`中的继承关系有些类似与dom层级;子集可以继承来自父类定义的属性和对象; 例如: app.js ```javascript var app = angular.module('myApp',[]); app.controller('parentController',function ($scope) { $scope.person = { name :'' } $scope.person.name = "chen"; }); app.controller('childController', function ($scope) { console.log($scope.person.name); $scope.person.name="thero"; }); ``` extends.html ```html
{{name}} 父级对象内容{{person.name}}
子级对象内容{{person.name}}
``` 注意事项 ==== * 在controller定义的对象,需要先声明后使用;下面的代码中,如果不定义`$scope.person` 对象,而是直接使用` $scope.person.name`时,是无法直接使用的,会报出下面的错误 ![name 未定义](WebContent/images/1.png); 先定义后使用的原则 ```javascript app.controller('parentController',function ($scope) { $scope.person = { name :'' } $scope.person.name = "chen"; }); ``` 当时由于集成的关系,在下面的代码中,没有定义name属性,却可以直接使用,这就集成的关系 ```javascript app.controller('childController', function ($scope) { console.log($scope.person.name); $scope.person.name="thero"; }); ``` * 如果在`dom`层级中,不存在这种父基本的关系,`$scope`是否还有集成关系呢? ```html
{{name}} 父级对象内容{{person.name}}
子级对象内容{{person.name}}
``` 上述的代码中,我们打破了层级关系,js代码不变;在访问页面的时候,`{{person.name}}` 该属性已经不存在了;由此我们可以发现,`controller`中属性的继承关系来源于`dom`层; 控制器的使用规范 ==== * 1、在`controller`中尽量不要对`dom`进行操作; * 2、可以将复杂的逻辑放到指令和服务中; ### `expression`表达式处理 可以利用一个示例来完成表达式的处理 ```html

{{parseValue}}

``` expressoin.js ```javascript var app = angular.module('myApp',[]); app.controller('MyController',function ($scope,$parse) { $scope.$watch('expr',function (newVal,oldVal,scope) { if(newVal!=oldVal){ var parseFun = $parse(newVal); $scope.parseValue = parseFun(scope); } }); }); ``` 代码解释 --- * 当我们在页面的表单中输入任何值的时候,下面的h2标签会对应显示值,如下图 ![expess 显示值](WebContent/images/3.png); * 和其他不同`expression`是,在表单`model`定义的`expr`名称 ,在表达式中`{{}}`我们 绑定了另一个值`parseValue`我们通过下面的代码,将`expr`和`parseValue`进行了关联起 来,来动态修改绑定的值; * 如果angularjs没能加载完所有的页面,在页面显示时将会出现`{{}}`字符串,我们可以使用 `
` `name`为`anguarjs`定义的`ng-model`内容 ```javascript var app = angular.module('myApp',[]); app.controller('MyController',function ($scope,$parse) { $scope.$watch('expr',function (newVal,oldVal,scope) { if(newVal!=oldVal){ var parseFun = $parse(newVal); $scope.parseValue = parseFun(scope); } }); }); ``` * 在`js`的文件中,可以通过`$watch`方法来监控`expr(model)`值的变化;该方法需要传递 2个参数,`model`对象以及回调函数,回调函数提供了3个参数(`newVal`,`oldVla`,scope); * `newVal` 修改`model`后的值, * `oldVal` 历史数值; * `scope` 上下文对象; * 在该`js`文件中定义的`$scope`与回调函数的scope是同一个对象;如下图![$scope对象](WebContent/images/2.png) * `$parse` `angularjs`方法,用于格式化数据等;如下图![$parse函数](WebContent/images/4.png); * `app.controller('MyController',function ($scope,$parse){} `左侧的代码中,提供了 2个参数,angularjs会自动注入这些参数; ### filter 过滤器 angularjs提供2中过滤的方式。可以退数字进行格式化,大小转小写;对数进行排序 * 使用`expression`来过滤数据,格式为`{{|}}` 其中`|` 左侧为值,右侧为表达式; * 使用`$filter`对象来进行过滤数据; 各类过滤器 ---- 1. `currency` 货币转换`50.035`,使用`{{50.035|currency:"RMB"}}`的形式就可以转换了 ```html currency 货币转换 53.035 {{50.035|currency:"RMB"}} ``` 在下面的运行结果我们可以发现,不仅将货币进行了转换,同时还进行了四舍五入;进行了数字的格式化 ![结果](WebContent/images/5.png) > 格式 {{数值|currency:'货币格式'}} 2. `date`日期格式化,这里只展示常用的日期格式化; ```html date 日期转换 {{today}} {{today|date:'yyyy'}} 或 {{today|date:'MM'}} 或 {{today|date:'dd'}} {{today|date:'HH'}} {{today|date:'mm'}} {{today|date:'ss'}} {{today|date:'yyyy-MM-dd HH:mm:ss'}} ``` ![](WebContent/images/5.png) 其中 * 'yyyy' 年 * 'MM' 月 * 'dd' 日 * 'HH' 小时 * 'mm' 分钟 * 'ss' 秒 * 'yyyy-MM-dd HH:mm:ss' 时间格式 > 格式:{{date|date:'时间格式'}} 3. `数组格式化` ```html 数组内容:['a','lerner','to','eat','pizza'] 按照含有e的字符串进行过滤 {{['a','lerner','to','eat','pizza']| filter:'e'}} ``` > 格式:{{数组|filter:要过滤的字符串}} 4. 对对象的过滤 ```html [{ 'name':'Ari', 'city':'san Francisco', 'favorite food':'pizza' },{ 'name':'Nate', 'city':'san Francisco', 'favorite food':'india food' }] 可以对对象进行过滤 {{ [{ 'name':'Ari', 'city':'san Francisco', 'favorite food':'pizza' },{ 'name':'Nate', 'city':'san Francisco', 'favorite food':'india food' }] | filter:{'favorite food':'pizza'} }} ``` ![](WebContent/images/6.png) > 格式:{{对象数组|filter:对象}} 5. 自定义数组过滤 ```html -- ['a','A','b'] 可以对对象进行过滤 {{ ['a','A','b'] | isCapitalized }} ``` ```javascript app.filter('isCapitalized',function () { return function (str) { var filterArray = new Array(); for(var i=0;i 格式:{{要过滤内容|方法名称}} **`注意:`**在自定义的方法中,不需要添加filter:也不用在方法后面添加括号 自定义filter的方式: ```javascript var app = angular.module('myApp',[]); app.filter('方法名称',function(){ return function(XXX){ return XXX; } }); ``` xxx就是`要过滤内容`,如果是数组需要添加遍历来完成操作;最终要有返回值 6. `json` 格式化转换 ```html {{ {name:"chen"} | json }} ``` > 格式{{ 对象或json | json }} 7. `limitto ` 截取数据 ```html {{ 'San francisco is very cloudy' | limitTo:3}}
{{ 'San francisco is very cloudy' | limitTo:-6}}
{{ ['a','b','c'] | limitTo:1 }} ``` > 格式{{ 对象或数组 | limitTo:3 }} 8. `orderby` 过滤内容 ```html {{ [{ "name":"Ari", "status":"awake" },{ "name":"Q", "status":"sleeping" },{ "name":"Nate", "status":"awake" }] |orderBy:'name':true }} ``` > 格式:{{数组|orderBy:属性:boolean}} 属性,要排序的对象中的一个属性,boolean倒序还是正序 9. `lowercase`转小写 ```html {{ 'aAc' | lowercase}}
``` > 格式:{{字符串|lowercase}} 10. 数字转换 ```html {{ 123456 | number}}
{{ 123456 | number:2}}
``` > 格式 {{数字|number:2}} 当有数字的时候表示保留的个数 ### directive 指令 ```html
directive 改变字体颜色
``` ```javascript var myApp = angular.module("myApp",[]); //E 表示dom元素 myApp.directive("superMane",function(){ return { restrict:'E', template:'
Here I am to save day
' } }); //A表示属性 ,注意在定义指令的时候是有大小写区分的,但是在html中没有大小写区分了 //定义时保持都为小写即可 myApp.directive("superalert",function () { return { restrict:'A', link:function(){ alert("hello wolrd by directive"); } } }); myApp.directive('superclass',function () { return { restrict:'EC', template:'myclass' } }); ``` ![](WebContent/images/11.png) > 注意: * A 处定义的名称中,如果含有大写字符,那么在html需要在大写字符前添加“-”即(`superMan`)--> `` * B 处,表示该指令可以存在的地方,只表示该元素可以可以出现的位置 * `E`表示`dom`元素 * `A`表示属性位置 * `C`表示`class`位置 * `M`表示注释位置 * C 处表示dom元素的内容,可以为函数,也可以直接为link:function ### `directive`通过指令来修改class内容 `html`定义了2个属性,`enter`和`leave`属性,在js文件中定义相关的指令,通过指令的方式来添加绑定事件,当 鼠标`over`在点我的div上时,控制台将会输出`I'am in side`;离开时控制台输出`I'am leave` ![](WebContent/images/13.gif) ```html
点我
``` `javascript`代码示例,下面的代码中我们定义了`enter`和`leave`两个指令,通过这两个指令,来绑定鼠标事件; ```javascript myApp.directive('enter',function () { return function (scope,element,attrs) { console.log(scope); console.log(element); console.log(attrs); element.bind("mouseenter",function () { console.log("I'am in side "); element.addClass("myclass"); }); } }); myApp.directive("leave",function () { return function(scope,element,attrs){ element.bind("mouseleave",function () { console.log("I'am leave"); element.removeClass(attrs.enter); }); } }); myApp.directive("leave",function () { return function(scope,element,attrs){ element.bind("mouseleave",function () { console.log("I'am leave"); element.removeClass(attrs.leave); }); } }); ``` 在`return function`中有3个参数 * scope作用域对象;**指令中返回的scope与全局的区别,当指令中定义了scope{}时,scope和$scope将不在是同一个对象** * 在指令中定义的`function(scope,element,attrs)` 这三个参数他们的重要,有占位符的概念,即对象和定义的名称无关;如果scope和element 的位置互换,为`function(element,scope,attrs)`在控制台输出时可以发现element为scope对象,由此可知对象与顺序有关,与定义的名称无关,如下图所示 ![](WebContent/images/26.png); * 上述代码中`controller`定义的`$scope`很重要,如下图: ![](WebContent/images/25.png) 如果该对象的名称被修改了,那么将会出现错误,如下图,这里注入的对象与顺序无关,但与名称有关: ![](WebContent/images/24.png) 但是我们可以通过另外一种方式来解决`$scope`名称注入错误的问题,如图,通过使用[]的方式就可以解决掉该问题 ![](WebContent/images/27.png) 此时我们发现a和b的顺序将会影响到注入对象,如下图 ![](WebContent/images/28.png) 在将A、B对应的别名修改后,发现他们与顺序发生着密切的关系 * elementdom元素对象 * attrs对象属性内容;我们可以在控制台进行输出这3个对象,以此来查看内容 ![](WebContent/images/12.png) 通过控制台输出的内容,我们发现attrs是一个对象,其中有`enter`和`leave`两个属性,我们可以通过 `attrs.enter` 或者`attrs.leave`来获取定义在div中的属性内容 ### 使用指令调用controller方法 如果想在指令中调用controller的方法,**该指令也需要在controller的作用域中,否则无法调用到该指令** ```html
你好啊
``` 与console和修改div颜色的指令写法类似,不同的是,在调用方法的地方,有3中形式可以调用; * `scope.functionName` `scope`.方法名称;该方法不推荐使用,我们不能很容易的知道在该作用域中,是否有该方法; * `scope.$apply("methodName")` `methodName`方法名称 注意的是,这里要填写的是字符串;在`html`页面中也需要加 如指令="方法名称" * `scope.$apply(attrs.directive);` `attrs`表示属性对象;`directiveName` 指令名称 ```javascript myApp.directive('enterMessage',function () { return function (scope,element,attrs) { element.bind("mouseenter",function () { console.log("123456"); scope.$apply(attrs.enterMessage);//scope.$apply("enterMessage()"); }) } }); ``` ### `directive` 中`templateUrl`使用方法 在上的指令中我们将div的信息都写了`template`中,这样识别度太低,我们可以使用`templateUrl`来完成 ```html
The content is {{content}}
``` ```javascript var myApp = angular.module("myApp",[]); myApp.directive("zippy",function () { return{ restrict:'E', transclude:true, scope:{ title:'@' }, templateUrl:'zippy.html', link:function (scope,element,attrs) { scope.isContentVisible = false; scope.toggleContent = function () { scope.isContentVisible = !scope.isContentVisible; }; } } }); ``` 代码说明: ==== 使用`templateUrl`可以将模板定义到指定的`html`文件中,如果不想创建新的`html`模块,可以在上面的`html`代码片段中加上 ```html ``` 注意的问题: * `template`更改为`templateUrl`; * 在`html`页面中需要定义`script`标签,该标签需要在`html` `ng-app`的作用域范围内;定义的`scripe`的`type`为`text/ng-template` * 也可以直接创建该文件,只需将dom内容添加到html页面中即可 **注意** * 模板信息的内容是被添加到缓存中的,可以通过下面的代码来获取缓存内容 `templateUrl:$templateCache.get('zippy.html')`,`$templateCache`需要定义在指令的function中,如下图: ![](WebContent/images/29.png); ### `directive`之间的交互 >指令之间的交互内容 ```html superMan
superman2 ``` ![](WebContent/images/14.png) * A处定义的指令名称,将会在其他指令中通过`require`的方式进行调用 * C处调用在`superhero`中定义的`controler` 即`指令名称+ctrl`来作为对象进行注入 * D通过C定义的`controller`来调用在`superhero`中定义的方法; * B注意这里的`scope`,如果该处没用定义,那么他们的作用域都来自于父类的`scope`,如果定义了,他们讲拥有各自的作用域如下图 > 定义了`scope`对象后输出内容 ![](WebContent/images/15.png) > 未定义`scope`对象后输出的内容,只想`superman`和`superman2`在控制台输出的内容一致;表明他们拥有相同的作用域 ![](WebContent/images/16.png) > 在指令中定义一个`controller`该方法中可以定义函数;在其他的指令中,可以注入`superhero`+Ctrl ```javascript myApp.directive('superhero',function () { return { restrict: 'E', scope:{}, controller:function ($scope) { $scope.abilities = []; this.addStrength = function () { $scope.abilities.push("addStrength"); }; this.addSpeed =function () { $scope.abilities.push("speed"); } this.addFlight = function () { $scope.abilities.push("addFlight"); } }, link: function (scope, element) { element.addClass("button"); element.bind("mouseenter",function () { console.log(scope.abilities); }); } }; }); myApp.directive("strength",function () { return { require: "superhero", link:function (scope,element,attrs,superHeroCtrl) { superHeroCtrl.addStrength(); console.log(superHeroCtrl.abilities); } }; }); myApp.directive("speed",function () { return { require: "superhero", link:function (scope,element,attrs,superHeroCtrl) { superHeroCtrl.addSpeed(); console.log(superHeroCtrl.abilities); } }; }); myApp.directive("flight",function () { return { require: "superhero", link:function (scope,element,attrs,superHeroCtrl) { superHeroCtrl.addFlight(); console.log(superHeroCtrl.abilities); } }; }); ``` ### scope中作用域内容 `@` 这是一个单项绑定的前缀标识符 使用方法:在元素中使用属性,好比这样`
`,注意, 属性的名字要用-将两个单词连接,因为是数据的单项绑定所以要通过使用{{}}来绑定数据。 > 如果在`return`当中没用使用`scope`的时候,如果想获得定义在`dom`中的属性内容,则需要下面的方式进行获取 ```javascipt myApp.directive("eat",function(){ return { template:"
{{love}}
", link:function(scope,element,attrs){ scope.love = attrs.love; } } }); ``` 通过调用`link`当中提供的`scope`方法来获取内容 ```html
``` 使用`@`的符号,可以来解决复杂的参数绑定内容 ```javascript myApp.directive("drink",function () { return { scope:{ flavor:"@" }, template:'
{{flavor}}
' } }); ``` 通过@符号,我们可以很轻松的获取到定义在`dom`中的值 ```html
``` `=` 这是一个双向数据绑定前缀标识符 使用方法:在元素中使用属性,好比这样``,注意,数据的双向绑定要通过=前缀标识符实现, 所以不可以使用`{{}}`。 代码示例 === ```html
``` 在指令中的socpe定义未`=`时,同事在dom层添加的内容为`flavor="{{ctrlFlavor }}"`,此时控制将会抛出 `angularjs.js:9503 Error: [$parse:syntax] Syntax Error: Token 'ctrlFlavor' is unexpected, expecting [:] at column 3 of the expression [{{ctrlFlavor }}] starting at [ctrlFlavor }}].` ![](WebContent/images/18.png) **解决方式** 将dom层中内容为`flavor="{{ctrlFlavor }}"`更改为`flavor="ctrlFlavor"` ```javascript var myApp = angular.module('drinkApp',[]); myApp.controller("AppCtrl",['$scope',function ($scope) { $scope.ctrlFlavor = "blackBerry"; }]); myApp.directive("drink",function () { return { scope:{ flavor:"=" }, template:'
{{flavor}}
' } }); ``` `&` 这是一个绑定函数方法的前缀标识符 使用方法:在元素中使用属性,好比这样``,注意,属性的名字要用-将多个个单词连接。 > `&`通过该方法可以获取到定义在`controller`中的方法 ![](WebContent/images/17.png) 代码说明: ==== * `A` 在controller中定义一个`method` * `B` 在指令的作用域中使用&方法来表示代替一个方法,其中定义的done属性,提供`template(C处)`使用,类似于指针的概念; * `C` 定义`ng-click`方法,来绑定定义在`scope`作用域中的方法,注意的是在`html`页面中仍然要使用定义在`controller` 定义的函数;`done`只是用来做指令和`controller`的桥梁 ### `transclusion`的使用 ```html
这是个面板
``` ```javascript var myApp = angular.module("myApp",[]); myApp.directive("eat",function () { return{ restrict:'E', template:'
hello World
' } }); ``` 上述的代码中,定义了eat个指令,刷新html页面后,可以发现,在原来定义的html被替换调用,如果不想将 原来已经存在的html页面替换掉,可以使用`transclusion`属性 ```javascript var myApp = angular.module("myApp",[]); myApp.directive("eat",function () { return{ restrict:'ECA', transclusion:true, template:'
hello World
' } }); ``` `**注意**` > 该配置只用当dom元素定义在指令元素之间时才会起到作用; > 如果上述条件没有满足,那么将会报错,内容为: `angularjs.js:9503 Error: [ngTransclude:orphan] Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found. Element: ` [translusion参考资料](http://www.ngnice.com/posts/28116df4d6f938) ### 另外一种方式来定义`controller` ```html
``` ```javascript var app = angular.module('myApp',[]); var phoneAppStuff = {} phoneAppStuff.controllers= {}; phoneAppStuff.controllers.AppCtrl = function ($scope) { this.sayHi = function () { alert("Hi"); } return $scope.Appctrl = this; } phoneAppStuff.directivies = {}; phoneAppStuff.directivies.panel = function () { return { restrict:'E' } } app.directive(phoneAppStuff.directivies); app.controller(phoneAppStuff.controllers); ``` 除了传统的方法来定义`controller`,我们还可以通过上面的代码,来完成对`controller`和`directive`来定义, 在` return $scope.Appctrl = this;`需要 注意的是,这里定义的`Appctrl`才是在`controller`定义使用的关键, 他影响了了`ng-click="Appctrl.sayHi()" ` 中定义的`Appctrl`的使用,这里是受影响大小写的; > 步骤与方法 1. `phoneAppStuff.controllers= {};`先声明一个变量; 2. 为该变量添加一个属性 ```javascript phoneAppStuff.controllers.AppCtrl = function ($scope) { this.sayHi = function () { alert("Hi"); } return $scope.Appctrl = this; } ``` 3. 与`angularjs`进行关联,这里注意的是,进行关联的是声明的变量即在第一步定义的`controller` ```javascript app.controller(phoneAppStuff.controllers); ``` ### 指令replace属性 > 该属性的作用,为true将会替换自定义标签的内容,且不在dom渲染该标签; ```html
``` 在下面的代码中我们讲replace:true 注释掉了,默认情况下为false,在浏览器渲染dom的时候会发现该指令 也作为了一个元素节点添加的html中了, ```javascript var app = angular.module("myApp",[]); app.directive("dumbPassword",function () { return{ restrict:'E', //replace:true, template:'
this is dumpPassword
' } }); ``` `定义replace:true`时,含有指令内容 ![replace:true`](WebContent/images/19.png) `定义replace:false`时指令的内容被删除了 ![replace:false](WebContent/images/20.png) ### 点击`div`折叠内容 `ng-show`控制页面显示与隐藏 定义两个div,用户输入的时候,在下方显示出来;当点击第一个第一个div时,第二个div显示出来 ```html
The content is {{content}}
``` ```javascript var myApp = angular.module("myApp",[]); myApp.directive("zippy",function () { return{ restrict:'E', transclude:true, scope:{ title:'@' }, template:'

{{title}}

hello world
', link:function (scope,element,attrs) { scope.isContentVisible = false; scope.toggleContent = function () { scope.isContentVisible = !scope.isContentVisible; }; } } }); ``` ![](WebContent/images/14.gif) 代码说明 --- * 上述代码中,我们定义了`isContentVisible`该属性可以用来控制点击第一个div时,第二个div显示与隐藏; * `ng-show`指令,用来控制`dom`的隐藏与显示 ### `angularjs` `watch`监听`ng-model` `watch`方法可以用来监听ng-model输入的值,如果我们讲ng-model定义到 input表单中,我们可以发现当我们更改值时该值function都会被调用; 下面我们设计一个情况,用户在表单输入内容,当输入的内容等于password时 我们修改输入的内容,将字体的背景更改为红色 ```html
``` ```javascript var app = angular.module("myApp",[]); app.directive("dumbPassword",function () { return{ restrict:'E', replace:true, template:'
\n \n
{{model.input}}
\n
', link:function (scope,element,attrs) { console.log("哈哈") //通过输出element内容我们可以知道页面这里的节点元素 指的是div template的整个内容 console.log(element); //设置当前输出文本中的内容 scope.$watch("model.input",function (value) { if(value=="password"){ console.log(element); element.find("div").toggleClass("alert"); }else{ element.find("div").toggleClass(); } }); } } }); ``` 代码解释 === ![](WebContent/images/21.jpg) * A处输出的element元素,这个元素在link function含有的参数;通过控制台的输出,我们可以观察到A与B输出的element对象 是相同的,如下图 ![](WebContent/images/23.png) * C处,angular提供的wacth方法可以用来监控model当中的值,在上述的案例中我们可以得知,当用户修改了表单中的值时 $watch方法 都可以实时监控到内容 * ![](WebContent/images/GIF.gif) #### 使用compile 来处理动态的元素内容 在上述的案例中我们使用了link提供的element参数来修改input表单中的值,我们还可以使用compile来,完成上的代码 ```javascipt app.directive("dumbspassword",function () { var validElment = angular.element("
{{model.input}}
"); this.link = function(scope,element,attrs){ scope.$watch("model.input",function (value) { if(value=="password"){ element.find("div").toggleClass("alert"); } }); } return { restrict:'E', repalce:true, template:'
\n \n
', compile:function (tElem) { tElem.append(validElment); return link; } } }); ``` [1]: ./images/1471683881029.jpg "1471683881029.jpg"