Exploring Angular 1.3: Binding to Directive Controllers
2015-06-23 09:15
826 查看
原文: http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html
Angular1.2引入了新的语法 controllerAs, 它让scope更加清楚、干净, 让controller更加聪明. 在我们的Angular应用中使用controllerAs可以避免开发者经常遇到的一些问题.
让我们用代码说事,有两个controller如下:
HTML如下:
ControllerTwo中的
如果我们想在ControllerTow中显示'Pascal'可以使用scope的$parent属性去引用父作用域:
然而使用$parent不是一个好的解决方案, 因为如果嵌套一多我们的代码就不利于维护了. 想象下如果你有4层或5层嵌套. 你的代码会变成
首先我们使用this替代$scope:
接下来, 我们修改ngController指令,使用controllerAs语法:
当使用controller的时候,我们就可以使用controllerAs. 例如在Angular的$routeProvider中我们也可以使用controllerAs.
指令也可以有controller, 所以我们在定义指令的时候也可以使用controllerAs.
下面的指令有一个隔离的scope,一个controller和一个使用controller属性的template:
如果这个name要进行双向绑定该怎么做呢?
如果我们在外部修改隔离scope的属性,他不会反应到controller的this对象中去. 在AngularJS1.2中, 当属性变化的时候我们使用$scope服务显示的重新对我们的scope赋值. 不要忘了把$watch的callback绑定到controller的this:
等等,开始去掉的$scope 现在又回来了. 而且现在为了进行双向绑定我们额外写了许多代码.
幸运的是, 这些在AngularJS 1.3中得到了很好的解决!
这意味, 当controller实例化, 隔离scope的初始值绑定到this上, 将来对这些属性值的改变也会自动反应.
看, 现在不需要$scope了.
下面的例子中. 不再在scope中定义scope属性了:
Angular1.2引入了新的语法 controllerAs, 它让scope更加清楚、干净, 让controller更加聪明. 在我们的Angular应用中使用controllerAs可以避免开发者经常遇到的一些问题.
controllerAs
做为命名空间
让我们用代码说事,有两个controller如下:function ControllerOne($scope) { $scope.foo = 'Pascal'; } function ControllerTwo($scope) { $scope.foo = 'Christoph'; } app.controller('ControllerOne', ControllerOne); app.controller('ControllerTwo', ControllerTwo);
HTML如下:
<div ng-controller="ControllerOne"> {{foo}} <div ng-controller="ControllerTwo"> {{foo}} </div> </div>
ControllerTwo中的
{{foo}}会覆盖ControllerOne中的
{{foo}}, 第一个{{foo}}会显示'Pascal', 第二个{{foo}}显示'Christoph'.
如果我们想在ControllerTow中显示'Pascal'可以使用scope的$parent属性去引用父作用域:
<div ng-controller="ControllerOne"> {{foo}} <div ng-controller="ControllerTwo"> {{$parent.foo}} </div> </div>
然而使用$parent不是一个好的解决方案, 因为如果嵌套一多我们的代码就不利于维护了. 想象下如果你有4层或5层嵌套. 你的代码会变成
$parent.$parent.$parent.$parent, 这是不是很糟糕?
首先我们使用this替代$scope:
function ControllerOne() { this.foo = 'Pascal'; } function ControllerTwo() { this.foo = 'Christoph'; }
接下来, 我们修改ngController指令,使用controllerAs语法:
<div ng-controller="ControllerOne as ctrl1"> {{ctrl1.foo}} <div ng-controller="ControllerTwo as ctrl2"> {{ctrl2.foo}} </div> </div>
当使用controller的时候,我们就可以使用controllerAs. 例如在Angular的$routeProvider中我们也可以使用controllerAs.
$routeProvider.when('/', { templateUrl: 'stateTemplate.html', controllerAs: 'ctrl', controller: 'StateController' });
指令也可以有controller, 所以我们在定义指令的时候也可以使用controllerAs.
app.controller('SomeController', function () { this.foo = 'bar'; }); app.directive('someDirective', function () { return { restrict: 'A', controller: 'SomeController', controllerAs: 'ctrl', template: '{{ctrl.foo}}' }; });
在指令中使用controllerAs的问题
我们说过,当使用controllerAs的时候controller的scope绑定到controller的this对象, 也就是说this代表我们的scope. 那么当指令有自己隔离的scope时,它会如何工作呢?下面的指令有一个隔离的scope,一个controller和一个使用controller属性的template:
app.directive('someDirective', function () { return { scope: {}, controller: function () { this.name = 'Pascal' }, controllerAs: 'ctrl', template: '<div>{{ctrl.name}}</div>' }; });
如果这个name要进行双向绑定该怎么做呢?
app.directive('someDirective', function () { return { scope: { name: '=' }, // ... }; });
如果我们在外部修改隔离scope的属性,他不会反应到controller的this对象中去. 在AngularJS1.2中, 当属性变化的时候我们使用$scope服务显示的重新对我们的scope赋值. 不要忘了把$watch的callback绑定到controller的this:
app.directive('someDirective', function () { return { scope: { name: '=' }, controller: function ($scope) { this.name = 'Pascal'; $scope.$watch('name', function (newValue) { this.name = newValue; }.bind(this)); }, // ... }; });
等等,开始去掉的$scope 现在又回来了. 而且现在为了进行双向绑定我们额外写了许多代码.
幸运的是, 这些在AngularJS 1.3中得到了很好的解决!
使用bindToController绑定controller
Angular 1.3在指令中引入了一个新的属性bindToController. 当设置bindToController为true时,属性是绑定到controller而不是scope.这意味, 当controller实例化, 隔离scope的初始值绑定到this上, 将来对这些属性值的改变也会自动反应.
app.directive('someDirective', function () { return { scope: { name: '=' }, controller: function () { this.name = 'Pascal'; }, controllerAs: 'ctrl', bindToController: true, template: '<div>{{ctrl.name}}</div>' }; });
看, 现在不需要$scope了.
1.4中的改善
在1.4中,
bindToController更加强大.在1.4中, 我们可以把所有要绑定到隔离scope的属性移到bindToController中.
下面的例子中. 不再在scope中定义scope属性了:
app.directive('someDirective', function () { return { scope: {}, bindToController: { someObject: '=', someString: '@', someExpr: '&' } controller: function () { this.name = 'Pascal'; }, controllerAs: 'ctrl', template: '<div>{{ctrl.name}}</div>' }; });
相关文章推荐
- 使用JavaScript的AngularJS库编写hello world的方法
- 简介可以自动完成UI的AngularJS工具angular-smarty
- 简介可以自动完成UI的AngularJS工具angular-smarty
- 使用JavaScript的AngularJS库编写hello world的方法
- angular指令
- 简述AngularJS相关的一些编程思想
- angularjs实战项目01-构建开发环境
- angularjs 中行的选定及行样式的设定
- angular依赖注入的理解(转)
- AngularJS从构建项目开始
- ionic angularjs 实现Enter键的提交
- ionic Angularjs 产生简单的列表滚动区域
- ionic AngularJS-设定ion-scroll div 动态高度
- AngularJS中使用service,并同步数据
- 移除AngularJS下URL中的#字符的方法
- 使用AngularJS创建单页应用的编程指引
- AngularJS入门心得4——漫谈指令scope
- 使用AngularJS实现可伸缩的页面切换的方法
- 使用AngularJS实现表单向导的方法
- 举例详解AngularJS中ngShow和ngHide的使用方法