当前位置: 移动技术网 > IT编程>脚本编程>AngularJs > 详解angular 中的自定义指令之详解API

详解angular 中的自定义指令之详解API

2017年12月12日  | 移动技术网IT编程  | 我要评论

自定义属性的四种类别

分为: 元素e,属性a,注释m,类c , 分别如下:

 <my-dir></my-dir>
 <span my-dir="exp"></span>
 <!-- directive: my-dir exp -->
 <span class="my-dir: exp;"></span>

简单创建一个指令

html结构:

<div ng-controller="myctrl">
 <div my-customer></div>
</div>

javascript结构:

angular.module('myapp', [])
  .controller('myctrl', ['$scope', function($scope) {
   $scope.customer = {
    name: 'naomi',
    address: '1600 amphitheatre'
   };
  }])
  .directive('mycustomer', function() {
   return {
    template: 'name: {{customer.name}} address: {{customer.address}}'
   };
  });

输出:

name: naomi address: 1600 amphitheatre

说明: 此处,myctrl 中定义的 $scope.customer 属性和属性值都在指令中的模板使用了。同样的,在指令return 对象中的 template 也可被替换成一路径,在路径html中书写和template中同样的代码,使用这种方式,可以操作更多代码。

templateurl 函数式编程

html结构:

<div ng-controller="myctrl">
  <div my-customer></div>
</div>

javascript结构:

 angular.module('myapp', [])
 .controller('myctrl', ['$scope', function($scope) {
  $scope.customer = {
   name: 'naomi',
   address: '1600 amphitheatre'
  };
   }])
 .directive('mycustomer', function() {
  return {
   templateurl: function(elem, attr) {
    return 'customer-' + attr.type + '.html';
   }
  };
 });

不同的templateurl ①

 name: {{customer.name}}

不同的templateurl ②

 address: {{customer.address}}

输出结果:

name: naomi
address: 1600 amphitheatre

说明: templateurl 的值可以是一个函数返回值,返回用于指令中的html模板的url。

隔离指令的作用域

① 通过不同的controller

html结构:

<div ng-app="myapp">
  <div ng-controller="myctrl1">
    <my-customer></my-customer>
  </div>
  <div ng-controller="myctrl2">
    <my-customer></my-customer>
  </div>
</div>

javascript结构:

angular.module('myapp', [])
  .controller('myctrl1', ['$scope', function($scope) {
   $scope.customer = {
    name: 'naomi',
    address: '1600 amphitheatre'
   };
  }])
  .controller('myctrl2', ['$scope', function($scope) {
   $scope.customer = {
    name: 'igor',
    address: '123 somewhere'
   };
  }])
  .directive('mycustomer', function() {
   return {
    restrict: 'e',
    templateurl: 'my-customer.html'
   };
  });

templateurl html 结构:

 name: {{customer.name}} address: {{customer.address}}

输出结果:

 name: naomi address: 1600 amphitheatre
 name: igor address: 123 somewhere

说明: 可见 不同的controller 有不同的作用范围。虽然指令一样,每次渲染都是分离的,所以我们可以抽象出来指令,用于html模板和代码的重用,封装。但是这样又不是很好,因为用了两个controller,我们可以使用指令中的scope而不是controller里的scope来替代,具体做法是将外部的scope 映射到指令内部的scope, 如下:

② 通过指令属性映射scope

html结构:

<div ng-app="myapp" ng-controller="myctrl">
 <my-customer info="naomi"></my-customer>
 <my-customer info="igor"></my-customer>
</div>

javascript 结构:

 angular.module('myapp', [])
  .controller('myctrl', ['$scope', function($scope) {
   $scope.naomi = { name: 'naomi', address: '1600 amphitheatre' };
   $scope.igor = { name: 'igor', address: '123 somewhere' };
  }])
  .directive('mycustomer', function() {
   return {
    restrict: 'e',
    scope: {
     customerinfo: '=info'
    },
    templateurl: 'my-customer-iso.html'
   };
  });

templateurl html结构:

name: {{customerinfo.name}} address: {{customerinfo.address}}

编译后的html结果:

 name: naomi address: 1600 amphitheatre
 name: igor address: 123 somewhere

③ 指令中的如果定义scope属性则html中的scope不会直接继承controller中的scope,在html中使用的都需要在scope:{}中声明,否则就是undefined

html 结构:

 <div ng-app="myapp" ng-controller="myctrl">
   <my-customer info="naomi"></my-customer>
 </div>

javascript结构:

 angular.module('myapp', [])
  .controller('myctrl', ['$scope', function($scope) {
   $scope.naomi = { name: 'naomi', address: '1600 amphitheatre' };
   $scope.vojta = { name: 'vojta', address: '3456 somewhere else' };
  }])
  .directive('mycustomer', function() {
   return {
    restrict: 'e',
    scope: {
     customerinfo: '=info'
    },
    templateurl: 'my-customer-plus-vojta.html'
   };
  });

  templateurl html结构:

name: {{customerinfo.name}} address: {{customerinfo.address}}
<br>
name: {{vojta.name}} address: {{vojta.address}}

html编译后的结果:

name: naomi address: 1600 amphitheatre
name: address:

说明: vojta 在指令中的scope没有被定义,不会直接继承在controller中的,那么他就是undefined,所以就是空白(什么都不显示)

可操作dom的指令

创建一个用于操作dom的指令,如果需要dom操作也都应该放在指令里。

html 结构:

 <div ng-app="myapp" ng-controller="myctrl">
  date format: <input ng-model="format"> <hr/>
  current time is: <span my-current-time="format"></span>
 </div>

javascript结构:

angular.module('myapp', [])
  .controller('myctrl', ['$scope', function($scope) {
    $scope.format = 'm/d/yy h:mm:ss a';
  }])
  .directive('mycurrenttime', function($interval, datefilter) {
    return {
     restrict: 'ae',
     link: function(scope, element, attr){
       var format, timeoutid;

      /* 更新时间函数 */
      function updatetime() {
       element.text(datefilter(new date(), format));
      }

      /* 监视时间格式的改变 */
      var attrwatch = scope.$watch(attrs.mycurrenttime, function(value) {
       format = value;
       updatetime();
      });

      /* 定时器 */
      timeoutid = $interval(function() {
       updatetime(); // update dom
      }, 1000);

      /* 页面跳转后移除定时器防止内存泄露 */
      element.on('$destroy', function() {
       $interval.cancel(timeoutid);
       attrwatch(); // 移除watch
      });
    }
   };
  });

说明: 在link函数中,操作dom节点,让dom的文本节点动态显示时间跳动。在页面跳转之后及时清除定时器和监视器以免发生内存泄漏。

通过transclude和ng-transclude创建可包裹其他元素的指令

html结构:

 <div ng-app="myapp" ng-controller="myctrl">
   <my-dialog>check out the contents, {{name}}!</my-dialog>
 </div>

javascript结构:

 angular.module('myapp', [])
  .controller('myctrl', ['$scope', function($scope) {
    $scope.name = 'tobias';
  }])
  .directive('mydialog', function() {
   return {
    restrict: 'e',
    transclude: true,
    scope: {},
    templateurl: 'my-dialog.html',
    link: function(scope) {
      scope.name = 'jeff';
    }
 };
});

templateurl html 结构:

 <div class="alert" ng-transclude></div>

编译后的html结构:

check out the contents, tobias!

说明: 指令中的scope本应隔离controller中的作用域的,但是由于设置了transclude=true选项,scope就会继承controller中的定义,所以最终是tobias而不是jeff。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网