自定义指令完成手风琴菜单 AngularJS

0x00 媒介

自定义指令在angular中是比较难的一个点,写了这么长时间也只会一些简朴的单指令,翻出《用AngularJS开辟下一代Web运用》,拿出内里的accordion例子好好啃一下。

这个例子团体比较简朴,然则照样须要相识一些点:

  1. 自定义指令语法

  2. 指令自力作用域:这里双向绑定用=

  3. 指令transclude

  4. 指令controller:require的controller作为link函数的第四个参数

  5. 指令link函数:每一个指令都实行一次,而compile只编译一次

0x01 结果

《自定义指令完成手风琴菜单 AngularJS》

很简朴的点击一个当前睁开,其他摺叠
个中expander是从controller中轮回出来的

预览:https://jsfiddle.net/savokiss/fh5sv52u/

0x02 View

  <accordion>
      <expander class='expander' ng-repeat='expander in expanders' expander-title='expander.title'>
          {{expander.text}}
      </expander>
  </accordion>

须要两个自定义指令accordion和expander

0x03 Controller

  $scope.expanders = [{
    title : 'Click me to expand',
    text : 'Hi there folks, I am the content that was hidden but is now shown.'
  }, {
    title : 'Click this',
    text : 'I am even better text than you have seen previously'
  }, {
    title : 'Test',
    text : 'test'
  }];

只要一个数组,定义了expander的title和text

0x04 Directives

父级指令accordion

myModule.directive('accordion',function(){
  return {
          restrict : 'EA',
          replace : true,
          transclude : true,
          template : '<div ng-transclude></div>',
          controller : function() {
              var expanders = [];
              this.gotOpened = function(selectedExpander) {
                  angular.forEach(expanders, function(expander) {
                      if (selectedExpander != expander) {
                          expander.showMe = false;
                      }
                  });
              };
              this.addExpander = function(expander) {
                  expanders.push(expander);
              };
          }
      };
});

这是手风琴菜单的父级指令,他的作用主要为:

  1. expanders用来寄存子指令的数据(即子集scope)

  2. addExpander要领用来在子指令挪用link函数时初始化expanders数组

  3. gotOpened要领用来供应给子指令封闭其他expander

子集指令expander

myModule.directive('expander', function(){
  return {
          restrict : 'EA',
          replace : true,
          transclude : true,
          require : '^?accordion',
          scope : {
              expanderTitle : '='
          },
          template : '<div>'
                   + '<div class="ex-title" ng-click="toggle()">{{expanderTitle}}</div>'
                   + '<div class="ex-body" ng-show="showMe" ng-transclude></div>'
                   + '</div>',
          link : function(scope, iElement, iAttrs, accordionController) {
              scope.showMe = false;
              accordionController.addExpander(scope);
              scope.toggle = function toggle() {
                  scope.showMe = !scope.showMe;
                  accordionController.gotOpened(scope);
              };
          }
      };
});

此指令申明:

  1. require了accordion指令,所以link函数的末了一个参数就是accordion的controller

  2. 自力scope中的expanderTitle用来双向绑定controller中的title

  3. transclude用来直接将view中的代码传进来,固然这里只显示了expander的text

  4. link函数供应了flag: scope.showMe,用来掌握expander的睁开状况

  5. link函数中初始化showMe为false,初始化将当前指令的scope添加到父级指令的expander数组中去

  6. 供应给本身scope.toggle要领,用来在切换开关状况,并挪用父级指令封闭其他兄弟

0x05 完

基本上就是这些点,全get到就差不多也能写相似的指令了~

    原文作者:savokiss
    原文地址: https://segmentfault.com/a/1190000004218698
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞