angular中controller在不同场景下的状态
来源:互联网 发布:linux服务器优点 编辑:程序博客网 时间:2024/06/05 18:43
- 一个controller写两遍会发生什么
- 都是controller,Directive和DOM谁先跑
- Directive link里的controller究竟是什么
angular的设计者提供了一种很独特的编码方式,让DOM变得更友好了。以前的DOM(至少我觉得)就是一堆堆起来的元素,光看DOM看不出来这页面到底要干嘛(超神的程序员除外),angular的DOM像是一篇能直接阅读的文章,他把方法直接写在了DOM里面,如果英语好的话(当然代码的编辑者也得有合适的命名规范),一个不懂前端的人估计都能直接读懂这个页面要实现的功能。
我认为提供这种能力最直观的就是controller(虽然真正干活的是以compile为首的一班 provider,不过他们一般在幕后),而controller在不同使用场景下,也会有不一样的表现。
这次我就分享一些我在controller学习使用中碰到的一些有意思的事情。
一个controller写两遍会发生什么?
controller在DOM中的情况挺简单的,不过也有一些有意思的地方,比如controller的属性究竟能在多大范围内起作用?
比如下面这段代码:通过改变输入框内的值改变页面上显示的名字,和统计次数的文字。
当然这个功能不用controller也可以实现,不过居然是说明controller的用途,就这么写了,controller在这里有两个方法:
init:初始化数据
saying:把输入值整理成一串字符串
HTML 绑定
<div ng-init="init()" ng-controller="hello"> <p>Name : <input type="text" ng-model="name"></p> <h1>Hello <span ng-bind="name | uppercase"></span></h1> <input type="text" ng-model="number"> <h2 ng-bind='saying()'></h2></div>
JS定义
var app=angular.module('tutorial',[]);app.controller('hello',function($scope){ $scope.init=function(){ $scope.name='Wang'; $scope.number=1; } $scope.saying=function(){ var time=parseInt($scope.number)+1; return 'Mr.'+$scope.name+',this is your '+time+' time to here'; }});
在html中绑定controller的逻辑基本就是这样:
DOM 通过ng-controller指定能操作自己的controller,
controller通过$scope将controller中定义的各种方法映射到DOM元素上(当然还得借助一大堆的ng兄弟去实现具体的工作)。
看着貌似挺简单,而且也很符合angular增强HTML功能的设计初衷。
不过下面我们来考虑一个有意思的问题
在同一个controller绑定在两个DOM元素上的时候,会发生什么?
<div ng-init="init()" ng-controller="hello"> <p>Name : <input type="text" ng-model="name"></p> <h1>Hello <span ng-bind="name | uppercase"></span></h1> <input type="text" ng-model="number"> <h2 ng-bind='saying()'></h2></div> //和上面一模一样的重复<div ng-init="init()" ng-controller="hello"> <p>Name : <input type="text" ng-model="name"></p> <h1>Hello <span ng-bind="name | uppercase"></span></h1> <input type="text" ng-model="number"> <h2 ng-bind='saying()'></h2></div>
虽然在现实情况下不太可能发生这种复制一遍的情况,但如果存在一个功能超全的controller,包含了很多能复用的方法(如果真有这种controller,你可以考虑把那些方法扔进service里了),那么他们的属性、数据会共享吗?比如在这种情况下,修改其中任意一个输入框的值,会有几个地方同步改变呢?
只会有一个改变,对于一个controller而言,不管他在多少个DOM上被绑定, 他的作用域(生命周期、或者别的什么,叫什么都行)只在这一块内,两块controller之间没有联系(就算都是修改
改变其中的一个对另一个不会有影响,这话是不是听着特别耳熟(好像在面向对象里面见过)。没错,虽然你看着只是写了一遍controller,但其实angular在使用的时候,还帮你new了一把,所以他们是彼此独立的两个对象。
如果你把代码改成这样,你能看到控制台输出两遍start。
app.controller('hello',function($scope){ //加个log console.log('controller start'); $scope.init=function(){ $scope.name='Wang'; $scope.number=1; } $scope.saying=function(){ var time=parseInt($scope.number)+1; return 'Mr.'+$scope.name+',this is your '+time+' time to here'; }}
都是controller,Directive和DOM谁先跑?
除了直接绑在DOM上,controller还能直接绑在Directive上。
比如下面这串代码:
HTML部分
<foo-directive foo='foo'></foo-directive>
JS部分
app.controller('hello2',function($scope,$http){ console.log('controller2 start');});app.directive("fooDirective", ['$http',function($http) { return { controller:'hello2', template : "<h1>自定义指令!</h1>" };}]);
页面上的效果就是打出一段自定义指定的文字。
hello2这个controller在这里可以说完全没有任何功能,可是已经足够说明问题,除了ng-controller以为,angular还能通过directive的controller属性去绑定controller,这个controller不用显式地写在页面上(看着好像有点违背angular的设计初衷,其实人家一开始的设计就是Directive为主,controller为辅的,只是我们一般都从controller开始学而已)。
同样,在这个Directive出现在页面上的时候,这个controller也会被new一份。
这种绑定在Directive上的controller还有一个特色,如果你把这个Directive和之前绑在DOM上的controller写在一个页面上,绑定DOM的controller和绑定Directive的controller谁会先被new?无论这两个DOM元素的先后顺序是什么样的,Directive里的controller都会先跑。
这其实涉及到angular的一个核心部件$compile,以后有机会再细说,这里就先知道Directive里的controller有执行的优先权就行(虽然貌似没啥大用,不过一些异步方案和未来的多线程可以优先放在Directive里)。
Directive link里的controller究竟是什么?
除了写在DOM里的ng-controller和写在Directive里的controller,还有一个常见的会出现controller的地方:Directive里的link。
//官方的link代码,5个默认参数function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }
link其实是Directive被$compile编译后执行的一个回调方法,一般用在对DOM元素进行改变的工作上。
个人觉得可以把link直接理解为jquery(当然只是功能上),选中一段DOM结构后对其进行操作。
一般来说link都被用来注册事件,关联数据什么的,不过这次我们关心的是link的第四个默认参数controller,这个controller和之前绑定在DOM或者Directive上的controller有什么关系?
一般来想,这个controller应该拥有绑定的controller(这里是hello2)所有的属性方法吧?
先做一个小实验:
试着打印看看controller究竟有什么。
app.directive("fooDirective", ['$http',function($http) { return { controller:'hello2', link:function(scope, $element, attrs, controllers) { console.log(controllers); }, template : "<h1>自定义指令2!</h1>" };}]);
打印出来一个空对象。。。hello2虽然没有什么功能可也不至于是个空对象吧,看来和我们理解的不太一样,这个controller不是hello2?那他是谁,来做什么?
在官方的解释中,这个controller貌似是个很强大的存在:
controller - the directive’s required controller instance(s) - Instances are shared among all directives, which allows the directives to use the controllers as a communication channel. The exact value depends on the directive’s require property
这么强大的说辞是个空是不是有点说不过去?等会儿,我们好像漏看了一些关键词:instance,controller as a communication channel。
angular的意思难道是要把controller的实例对象本身作为一个传递中介?
既然是实例对象,我把hello2稍微改动了一下:
app.controller('hello2',function($scope,$http,wiki){ console.log('controller2 start'); $scope.hello=function(a){ var addd=a; console.log(addd); } return { hello3:function(a){ alert(a); } }});
然后再跑一遍代码:
控制台打出来hello3 function,好激动啊,原来实例指的是这个。那么在实际使用中,我们就可以用controller通过$scope取得不同DOM的值,然后返回给Directive,这是不是就是所谓的communication channel?
居然是communication channel,而且官方的解释还是controllers,那是不是意味着可以传多个controller进去,实现不同controller直接的交互?
果断试试这个,require注入另一个controller hello(require要注入多个controller第一位必须得是自身)
app.directive("fooDirective", ['$http',function($http) { return { controller:'hello2', require:['fooDirective','hello'], link:function(scope, $element, attrs, controllers) { console.log(controllers); }, template : "<h1>自定义指令2!</h1>" };}]);
果断报错,controller不能解析。
其实当然不能解析,hello这个controller还没有实例化怎么可能解析,而且官方也说这是用在Directive直接的controller信息传递,也就是说是用在Directive中实例化的controller上。
那么是不是可以改成这样?
//一个新的directive<runoob-directive aaa='aaa'> <foo-directive foo='foo'></foo-directive></runoob-directive>
app.controller('hello',function($scope){ console.log('controller3 start'); return { hello1:function(a){ alert(a); } }});app.directive("runoobDirective", ['$http',function($http) { return { controller:'hello', link:function(scope, $element, attrs, controllers) { console.log(controllers); } };}]);app.directive("fooDirective", ['$http',function($http) { return { controller:'hello2', require:['fooDirective','^runoobDirective'], link:function(scope, $element, attrs, controllers) { console.log(controllers); }, template : "<h1>自定义指令2!</h1>" };}]);
新建了一个Directive,然后很开心的看到控制台打出来一个数组,两个实例化的function,分别来自hello和hello2.而且如果这时候你试试查看scope的话,你会很神奇的发现他们的$id是一样的,也就是说这么写能让两个Directive共享一次compile,感觉这在需要大量数据绑定的地方是一个可以很节约性能的功能。
另外,在Directive中注入多个controller还能让他们彼此继承对方的方法属性(就行call和apply),配合watch用在多个controller通信中感觉很有前途。
- angular中controller在不同场景下的状态
- 同一个Controller里的同一个Service实例,在当前的Controller里的不同方法中状态不一致
- angular,不同的controller间通信
- angular 在controller中共享数据的几种方式
- 关于java中路径的思考:相对路径,以及在不同场景下的区别 classpath
- fiddler在不同场景下的强大作用
- EditText 在不同场景下调用软键盘的总结
- angular中controller之间的通信
- Springmvc 在同一个controller和不同的controller中进行重定向redirect和转发forward:
- Springmvc 在同一个controller和不同的controller中进行重定向redirect和转发forward
- Fragment在不同场景中生命周期的问题
- 如何在不同的controller下设置不同的状态栏颜色
- java的synchronized的使用场景简介以及在不同场景下的差异
- angular controller的使用
- Android在不同状态下的调试方法
- 不同状态下的button
- angular中控制器(controller)之间传递参数的方式
- Angular中ng-controller父子级嵌套的相关属性
- 使用FileDownLoader下载文件
- git pull时报错fatal: Could not read from remote repository.
- 产生不同随机数,输入数据用折半查找判断数据是否存在。
- DOM 位置大小操作
- 今日头条 面试题一例
- angular中controller在不同场景下的状态
- 掩码学习笔记(不断更新)
- Spark学习笔记(一)
- perl unload oracle gbk
- Linux--多线程拷贝文件案例及其传参说明
- 最小栈
- 排队买票(歌)
- ElasticSearch性能调优
- leetcode283~Move Zeroes