你的位置:首页 > Java教程

[Java教程]AngularJS自定义Directive初体验


 

通常我们这样定义个module并随之定义一个controller.

 

var app = angular.module('myApp', []);app.controller('CustomersController', ['$scope', function($scope){  var counter = 0;    $scope.customer = {    name:'',    street:''  };    $scope.customers = [    {      name:'',      street:''    },    ...  ];    $scope.addCustomer = function(){    counter++;    $scope.customers.push({      name:'' + counter,      street: coutner + ''    });        $scope.changeData = function(){      counter++;      $scope.customer = {        name: '',        street:counter + ''      };    }  }}]);

 


■ 使用ng-include引用子视图

在一个子视图中可以使用CustomersController,子视图的名称是:child.html

 

Name:{{customer.Name}}
Street:{{customer.street}}

然后在一个主视图中比如是index.html使用子视图:

<div ng-include="child.html"></div>

■ 初识自定义directive

如果使用自定义directive也可以做到。

 

angular.module('myApp').directive('myInfo', function(){  return{    template:'Name:{customer.name}<br/>Street:{{customer.street}}'  };})

 

在index.html主视图中可以这样使用自定义的directive。

<div my-info></div>

为什么myInfo到了视图中变成了my-info?这是一个惯例,比如我们经常用到的ng-repeat,在AngularJS中的源代码中是ngRepeat。还有,为什么,自定义的名称为myInfo的directive可以使用CustomersController的scope呢?因为主视图index.html中使用了CustomersController,而同在index.html视图中的<div my-info></div>共享了CustomersController的scope。

directive通常的用法包括如下:

 

angular.module('modulename')  .directive('myDirective', function(){    return {      restrict: 'EA', //E表示element, A表示attribute,C表示class,M表示commnent,即注释      scope:{        title: '@' //@读属性值,=双向绑定,&用户函数      }      template: '<div>{{myVal}}</div>',      templateUrl: 'app/sample.html',      controller: 'myController',      link:function($scope, element, attrs){}//DOM操作    };  })

 

■ 自定义direcitve操作DOM元素

 

app.directive('myDomDirective', function(){  return {    link: function($scope, ele, attrs){      ele.bind('click', function(){        ele.html('');      });            ele.bind('mouseenter', function(){        ele.css('background-color','red');      });            ele.bind('mouseleave', function(){        ele.css('background-color','white');      });    }  };});

 

在页面中这样使用:

<div my-dom-directive></div>

■ 封闭自定义directive的scope

默认情况下,自定义的directive的会共享父scope,但是,有时候我们希望自定义的directive的scope是封闭的、独立的,比如希望自定义的direcitve被用在多处。

只需要加上scope属性就好了,如下:

 

angular.module('myDirecitve', function(){  return {    scope:{},    template: ''  }});

 

scope属性接受一个对象,在该对象中可以定义独立scope内的属性,而属性值的写法有三种,分别是@,=,&

● 使用@,外部scope赋值不影响封闭scope中的变量

 

angular.module('myApp').directive('myIsolateScopeWithName', function(){  return {    scope:{      name: '@'    },    template: 'Name:{{name}}',    controller: 'MyController'  };});

 

在封闭的scope中定义了一个name变量,占位符@表示这里接受一个值。

如何给这里的变量赋值呢?

一种是把name成为一个属性来接收值:

<div my-isolated-scope-with-name name="{{ customer.name }}"></div>

一种是在MyController中给name赋值:

$scope.name = '';

如果把name="{{ customer.name }}"改成myname="{{ customer.name }}"呢?

那就需要这样定义:

angular.module('myApp').directive('myIsolateScopeWithName', function(){  return {    scope:{      name: '@myname'    },    template: 'Name:{{name}}',    controller: 'MyController'  };});

 

● 使用=,外部scope赋值会影响封闭scope中的变量

 

angular.module('myApp').directive('myIsolateScopeWithEqual', function(){  return {    scope:{      customer: '='    },    template: '<ul><li ng-repeate="prop in customer">{{prop}}</li></ul>'  };});

 

注意,这里的customer是作为变量在使用,而不是{{customer}},一旦外部的赋值发生变化会影响独立scope中的customer变量值。同样,一旦独立scope中的customer值发生变化,也会影响外部的scope的customer属性值。

外部这样使用:

<div my-isolated-scope-with-equal customer="customer"></div>


● 使用&,允许外部scope传递一个函数给封闭scope

 

angular.module('myApp').directive('myIsolateScopeWithFunction', function(){  return {    scope: {      datasource: '=',      action:'&'    },    template: '<ul><li ng-repeat="prop in datasource">{{ prop }}</li></ul> ' + '<button ng-click="action()">Change Data</button>'  };});

 

这样使用这个directive

 

<div my-isolated-scope-with-function   datasource="customer"   action="changeData()"></div>

 

changeData方法被定义在了controller里面:

 

$scope.changeData = function () {   counter++;   $scope.customer = {     name: 'James',     street: counter + ' Cedar Point St.'   };};

 

如何让外部scope传递一个带参函数给封闭scope呢?

 

angular.module('directivesModule').directive('isolatedScopeWithController', function () {  return {    restrict: 'EA',    scope: {      datasource: '=',      add: '&',    },    controller: function ($scope) {      ...            $scope.addCustomer = function () {        //Call external scope's function        var name = 'New Customer Added by Directive';        $scope.add({ name: name });        //Add new customer to directive scope        $scope.customers.push({          name: name,          street: counter + ' Main St.'        });      };    },    template: '<button ng-click="addCustomer()">Change Data</button>' +         '<ul><li ng-repeat="cust in customers">{{ cust.name }}</li></ul>'  };});

 

在页面中这样调用:


<div isolated-scope-with-controller datasource="customers" add="addCustomer(name)"></div>

■ 允许自定义的direcitve被嵌套


只要把tranclude设置成true就可以。

 

"use strict";angular.module("psFramework").directive("psFramework",function(){  return {    transclude: true,    scope:{      title: '@',      subtitle:'@',      iconFile:'@'    },    controller: "psFrameworkController",    templateUrl: "ext-modules/psFramework/psFrameworkTemplate.html"  };})

 

然后在页面中就可以这样使用:

 

<ps-framework title="", subtile="", icon-file="">  <ps-menu>    ...  </ps-menu></ps-framework>

 

参考:https://weblogs.asp.net/dwahlin/