Angular - 在编译指令之前,动态地将编译的html片段添加到指令中

时间:2016-03-24 20:40:37

标签: angularjs ionic-framework

我试图在Ionic中动态地将指令添加到另一个指令中,例如:

<ion-nav-buttons side="right">
  // If the page has my-directive, add here a my-button to control it
</ion-nav-buttons>

我试图从另一个更深层次的指令中做到这一点。 我试试codepen

背景 我想,如果我在更深处使用my-directive,那么my-directive会动态添加一个按钮navbar,可以控制my-directive

修改:我再次尝试codepen 2,但仍有一些问题:

  • 当转到指令不存在的页面时,也应该删除该按钮。
  • 只有在指令所在的页面上直接启动时,才会显示该按钮。如果你从其他地方开始并导航到它,它就无法工作。
  • 在某个地方,我有一个等待0毫秒的$ timeout,没有工作,但为什么这是必要的。

1 个答案:

答案 0 :(得分:0)

您可以为导航栏创建一个指令,并将标记传递给指令的isoltated范围。

可以使用$rootScope或工厂进行传递。我更喜欢工厂,但在演示中我使用了rootScope来传递。

我也不喜欢演示中传入的范围。它正在工作,但我认为最好将处理程序存储在工厂中。然后,工厂可以管理导航栏中图标的创建以及按钮所需操作的事件处理程序。

请查看以下演示或此HTMLElement.click()

&#13;
&#13;
angular.module('ionicApp', ['ionic'])

.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
  
    $ionicConfigProvider.views.swipeBackEnabled(false);
    $ionicConfigProvider.views.maxCache(0);
  
  $stateProvider
    .state('eventmenu', {
      url: "/event",
      abstract: true,
      templateUrl: "templates/event-menu.html"
    })
    .state('eventmenu.home', {
      url: "/home",
      views: {
        'menuContent' :{
          templateUrl: "templates/home.html"
        }
      }
    })
    .state('eventmenu.checkin', {
      url: "/check-in",
      views: {
        'menuContent' :{
          templateUrl: "templates/check-in.html",
          controller: "CheckinCtrl"
        }
      }
    })
    .state('eventmenu.attendees', {
      url: "/attendees",
      views: {
        'menuContent' :{
          templateUrl: "templates/attendees.html",
          controller: "AttendeesCtrl"
        }
      }
    })
  
  $urlRouterProvider.otherwise("/event/home");
})

.controller('MainCtrl', function($scope, $ionicSideMenuDelegate) {
  $scope.toggleLeft = function() {
    $ionicSideMenuDelegate.toggleLeft();
  };
})

.controller('CheckinCtrl', function($scope) {
  $scope.$on('$ionicView.afterEnter', function() {
    console.log('entered');
  });
})

.controller('AttendeesCtrl', function($scope) {
})
.directive( 'dynNavbar', function($compile) {
  return {
    scope: {
      optional: '='
    },
    template: '<button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button><div class="dynButton"/>',
    link: function(scope, element) {
      scope.$watch('optional', function(){
        var dynButton = scope.optional; 
        console.log(scope.optional, element, element[0].querySelector('.dynButton'), $compile(dynButton.html)(scope));
       angular.element(element[0].querySelector('.dynButton')).replaceWith($compile(dynButton.html)(dynButton.scope));
      });
      
    }
  }
})
.directive('test', function($compile) {
  return {
        restrict: 'E',
        replace: true,
        template: '<p ng-style="{color: styleFlag}">use this directive, with the button in the navbar</p>',
        controller: function($scope, $rootScope) {
          $rootScope.injectedButton = {html: '<a class="button button-icon icon ion-eye" ng-click="cry()"></a>',
            scope: $scope
          };             
          var styleFlag = false;
          
          $scope.cry = function () {
              console.log('buhuhuhu');
              styleFlag = !styleFlag; // change style just as example
              $scope.styleFlag = styleFlag ? 'red': 'black';
              //console.log(styleFlag, $scope.styleFlag);
            };
        },
        link: function(scope, el, attrs){
            
            // -----------------------------------
            // ADD BUTTON IN NAVBAR
            // -----------------------------------
            //scope.$on('$ionicView.afterEnter', function(){
             /*   var nav = document.getElementsByClassName('nav-bar-block');
                if (nav[0].getAttribute('nav-bar') == 'active' || nav[0].getAttribute('nav-bar') == 'entering') {
                    nav = angular.element(nav[0].getElementsByClassName('right-buttons')[0]);
                }
                if (nav[1] && nav[1].getAttribute('nav-bar') == 'active' || nav[1] && nav[1].getAttribute('nav-bar') == 'entering') {
                    nav = angular.element(nav[1].getElementsByClassName('right-buttons')[0]);
                }
              console.log(nav);
                nav.append($compile('<a class="button button-icon icon ion-eye" ng-click="cry()"></a>')(scope));
            // });
*/
            // -----------------------------------
            // FUNCTION FOR THE BUTTON
            // -----------------------------------
            /*scope.cry = function () {
              console.log('buhuhuhu');
            };*/
        }
    }
});
&#13;
<html ng-app="ionicApp">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">

    <title>Side Menus</title>

    <link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
    <script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
  </head>

  <body ng-controller="MainCtrl">

    <ion-nav-view></ion-nav-view>

    <script id="templates/event-menu.html" type="text/ng-template">
      <ion-side-menus enable-menu-with-back-views="false">

        <ion-side-menu-content>
          <ion-nav-bar class="bar-positive">
            <ion-nav-back-button></ion-nav-back-button>

            <ion-nav-buttons side="left">
              <button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button>
            </ion-nav-buttons>
            
            <ion-nav-buttons side="right">
              <!--<button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button>-->
              <dyn-navbar optional="injectedButton"/>
            </ion-nav-buttons>
          </ion-nav-bar>

          <ion-nav-view name="menuContent"></ion-nav-view>
        </ion-side-menu-content> 

        <ion-side-menu side="left">
          <ion-header-bar class="bar-assertive">
            <h1 class="title">Left Menu</h1>
          </ion-header-bar>
          <ion-content>
            <ul class="list">
              <a href="#/event/check-in" class="item" menu-close>Check-in</a>
              <a href="#/event/attendees" class="item" menu-close>Attendees</a>
            </ul>
          </ion-content>
        </ion-side-menu>

      </ion-side-menus>
    </script>

    <script id="templates/home.html" type="text/ng-template">
      <ion-view view-title="Welcome">
        <ion-content class="padding">
          home: <test></test>
        </ion-content>
      </ion-view>
    </script>

    <script id="templates/check-in.html" type="text/ng-template">
      <ion-view view-title="Event Check-in">
        <ion-content>
          checkin: <test></test>
        </ion-content>
      </ion-view>
    </script>

    <script id="templates/attendees.html" type="text/ng-template">
      <ion-view view-title="Event Attendees">
        <ion-content>
          attendees: <test></test>
        </ion-content>
      </ion-view>
    </script>

  </body>
</html>
&#13;
&#13;
&#13;