在Angular-Material中,当关闭对话框时,如何强制嵌套在对话框中的指令被销毁?

时间:2016-08-30 21:11:17

标签: javascript jquery angularjs angular-material

我有一个对话框模板,其中包含一个指令,用于触发对后端的定期调用以检查新内容。在指令的$ destroy函数中取消间隔,当我离开时它按预期工作。但是,当我关闭模态时,嵌套指令的范围不会被破坏,即使它是a)从DOM中移除而b)在未保留的范围下。我还需要什么样的设置才能强制销毁嵌套指令?

我目前的设置有点复杂,但它基本上归结为以下几点:

编辑:说明问题的工作插件:https://plnkr.co/edit/BAlzEw2wjEuYWDVPZoCd

的index.html

<!DOCTYPE html>
<html ng-app="testapp">

  <head>
    <script>document.write('<base href="' + document.location + '" />');</script>

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.1.1/angular-material.min.css" />

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular-animate.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular-aria.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.js"></script>

    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>

    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
    <script src="directive1.js"></script>
    <script src="directive2.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <placeholderdirective></placeholderdirective>

    <br />

    <a href ng-click="openDialog1 ()">Re-open dialog</a>
  </body>
</html>

dialog1.html

<md-dialog id="dialog1" aria-label="dialog">
  <md-toolbar layout="row" class="dialog-header">
    <div flex="grow" class="dialog-title">
      <h4>
        Dialog 1
      </h4>
    </div>
    <a flex="nogrow" href ng-click="$root.hideDialog ()" class="close-dialog">&times;</a>
  </md-toolbar>

  <md-dialog-content>
    <my-directive></my-directive>
  </md-dialog-content>
</md-dialog>

的script.js

var app = angular.module('testapp', ['ngAnimate', 'ngAria', 'ngMaterial']);

app.value('DIALOGS',
  {
    'DEFAULTS':
    {
      autoWrap: false,
      clickOutsideToClose: true,
      disableParentScroll: true,
      escapeToClose: true,
      focusOnOpen: true,
      fullscreen: false,
      hasBackdrop: true,
      parent: $('body'),
      preserveScope: true
    },
    'DIALOG1':
    {
      templateUrl: 'dialog1.html'
    }
  });

app.controller ('MainCtrl', function ($mdDialog, $rootScope, $scope, DIALOGS)
  {
    $scope.test = 'Test';

    $scope.openDialog1 = function ()
    {
      var params = _.assign (DIALOGS.DEFAULTS, DIALOGS.DIALOG1);
      $mdDialog.show (params);
    };

    $rootScope.hideDialog = function ()
    {
      $mdDialog.hide ();
    }
  });

directive1.js

//-- PLACEHOLDER DIRECTIVE --
angular
  .module('testapp')
  .directive('placeholderdirective', ['$mdDialog', '$rootScope', 'DIALOGS',
    function($mdDialog, $rootScope, DIALOGS) {

      return {
        restrict: 'E',
        scope: {

        },
        template: '<div></div>',
        link: function($scope, element, attributes, controller) {
          function init() {
            //All modals use the default values unless overridden in
            //their own Object. This simply mixes the two into a single
            //object, prioritizing the second argument
            var params = _.assign(DIALOGS.DEFAULTS, DIALOGS.DIALOG1);

            //Create an isolate scope for the dialog. This gets properly
            //destroyed when the dialog closes
            var child = $rootScope.$new(true);

            params.scope = child;

            //Display the modal
            $mdDialog.show(params);
          }

          init();

          /**
           * Called when the directive is destroyed
           **/
          $scope.$on('$destroy', function(event) {
            alert('Destroying the placeholder');
          });
        }
      };
    }
  ]);

directive2.js

//-- NESTED DIRECTIVE --
angular
  .module('testapp')
  .directive('myDirective', ['$rootScope',
    function($rootScope) {

      return {
        restrict: 'E',
        scope: {
          //Note that this scope is also isolated
        },
        template: '<div>Hello, world!</div>',
        link: function($scope, element, attributes, controller) {
          /**
           * Called when the directive is destroyed
           **/
          $scope.$on('$destroy', function(event) {
            //Doesn't get called until the primary scope is destroyed,
            //but I would like it to fire when the dialog closes
            alert('Destroying my directive!');
          });
        }
      };
    }
  ]);

0 个答案:

没有答案