Exploring Angular 1.3: Binding to Directive Controllers

原文: http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html

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>‘
  };
});
时间: 2024-10-18 09:50:36

Exploring Angular 1.3: Binding to Directive Controllers的相关文章

[AngularJS - thoughtram] Exploring Angular 1.3: Binding to Directive Controllers

The post we have: http://www.cnblogs.com/Answer1215/p/4185504.html gives a breif introduce about bindToController on the directive. Here is a blog about bindToController from thoughtramwhich explains in detail why bingToController comes into handy an

angular 自定义指令详解 Directive

在angular中,Directive,自定义指令的学习,可以更好的理解angular指令的原理,当angular的指令不能满足你的需求的时候,嘿嘿,你就可以来看看这篇文章,自定义自己的指令,可以满足你的各种需求的指令. 本篇文章的参考来自  AngularJS权威指南 , 文章中主要介绍指令定义的选项配置 废话不多说,下面就直接上代码 //angular指令的定义,myDirective ,使用驼峰命名法 angular.module('myApp', []) .directive('myDi

[Angular 2] Property Binding

Property Binding is bind property NOT attribute! import {Component, Input, Output, EventEmitter} from 'angular2/core'; @Component({ selector: 'hero-item', styles: [ '.active {color: red}' ], template: ` <li [class.active]="isSelected" [attr.a

angular的GitHub Repository Directive Example学习

angular的GitHub Repository Directive Example学习 运行下面代码 <!DOCTYPE html><html ng-app="myApp"><head>     <meta charset="utf-8" />     <title>GitHub Repository Directive Example</title>       <script sr

Angular数据双向绑定

Angular数据双向绑定 AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀的前端JS框架,已经被用于Google的多款产品当中.AngularJS有着诸多特性,最为核心的是:MVVM.模块化.自动化双向数据绑定.语义化标签.依赖注入等等. 一.什么是数据双向绑定 Angular实现了双向绑定机制.所谓的双向绑定,无非是从界面的操作能实时反映到数据,数据的变更能实时展现到界面. 一个最简单的示例就是这样: <div ng-control

Scope Directive

---------------------------Scope-------------------------------- https://docs.angularjs.org/guide/scope What are Scopes? Scope is an object that refers to the application model. It is an execution context for expressions. Scopes are arranged in hiera

[转贴]有关Angular 2.0的一切

对Angular 2.0的策略有疑问吗?就在这里提吧.在接下来的这篇文章里,我会解释Angular 2.0的主要特性区域,以及每个变化背后的动机.每个部分之后,我将提供自己在设计过程中的意见和见解,包括我认为仍然需要改进设计的重要部分. 注意:本文所反映是2014年11月6日的状态记录.如果你在较长时间之后读到此文,请检查一下我设计上是否有所变更. AngularJS 1.3 在开始讨论Angular的未来之前,我们先花点时间看看当前的版本.AngularJS 1.3是迄今为止最优的Angula

angular学习(一)—— 概览

1. 文章简述 这篇主要通过几个小例子把angular的常用组件简单介绍一下 2. data binding 下面是一个简单通过quantity和costs计算Total的示例 <div ng-app ng-init="qty=1;cost=2"> <b>Invoice:</b> <div> Quantity: <input type="number" min="0" ng-model=&qu

angular读书笔记(三)

(三)使用路由和$location切换视图 app.js: angular.module('shop',['ngRoute','ngResource','shop.controllers','shop.services','shop.filter']).config(['$routeProvider','$locationProvider','$interpolateProvider',function($routeProvider, $locationProvider, $interpolat