AngularJS自定义指令 - 将隔离范围映射到新的子范围

时间:2016-02-05 06:42:32

标签: angularjs angularjs-scope

我为bootstrap警报创建了一个自定义指令。我的警报显示正常(硬编码和数据绑定)。根据警报类型,我希望根据返回的范围值(成功,信息,警告,危险)在警报消息中显示唯一标头。目前我已将该类型传递到<h1>,但我不想要这些值,它们需要自定义。

<!-- data binding example -->
<trux-alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)">{{alert.msg}}</trux-alert>

<!-- hard coded example -->
<trux-alert close="close" type="warning">This is an important warning message!</trux-alert>

在我的指令中,范围是使用范围隔离的:&#39; @&#39; (单程)

.directive('truxAlert', function() {
    return {
        scope: {
            type: '@',
            close: '&'
        },
        replace: true,
        transclude: true,
        template: 
            '<div class="alert" '+
                  'ng-class="[\'alert-\' + (type || \'warning\'), closeable ? \'alert-dismissible\' : null]" '+
                  'role="alert">'+
              '<button ng-show="closeable" '+
                       'type="button" class="close" '+
                       'ng-click="close({$event: $event})" '+
                       'data-dismiss="alert" aria-label="Close">'+
                  '<span aria-hidden="true">&times;</span>'+
                  '<span class="sr-only">Close</span>'+
              '</button>'+
              '<h1>{{type}}</h1>'+
              '<div ng-transclude></div>'+
            '</div>',
        link: function (scope, element, attrs) {}
    }
});

如果通过数据绑定提取所有值,这会更容易,但我需要允许手动硬编码选项。我知道单向隔离范围&#39; @&#39;我不能通过DOM操作来改变这些值。我无法使用&#39; =&#39;或者&#39;&amp;&#39;对于双向,因为值是字符串。

如何解决此问题?

2 个答案:

答案 0 :(得分:0)

我的建议是有一个属性用于控制指令警报的打开/关闭状态以及解雇处理函数的另一个属性。

angular.module("myApp").directive('truxAlert', function() {
    return {
        scope: {
            type: '@',
            dismissHandler: '&',
            title: '@',
            open: '='
        },
        replace: true,
        transclude: true,
        template:
            '<div class="alert" ng-show="open" '+
                  'ng-class="[\'alert-\' + type]" '+
                  'role="type">'+
              '<button type="button" class="close" '+
                       'ng-click="truxClose($event)" '+
                       'data-dismiss="alert" aria-label="Close">'+
                  '<span aria-hidden="true">&times;</span>'+
                  '<span class="sr-only">Close</span>'+
              '</button>'+
              '<h1>{{title+" "+type}}</h1>'+
              '<div ng-transclude></div>'+
            '</div>',
        link: function (scope, element, attrs) {
            console.log("truxAlert linking");
            if (!scope.type) { scope.type="warning" }
            scope.truxClose = function(event) {
                console.log("truxClose "+event);
                if (attrs.dismissHandler) {
                    scope.dismissHandler({$event: event});
                    return;
                }
                scope.open = false;
            };
        }
    };
});

指令的链接功能确定dismiss-handler属性是否存在,并调用解除处理程序或直接关闭警报。

DEMO PLNKR显示该指令同时使用ng-repeat指令并以独立方式使用。

答案 1 :(得分:0)

也许,我不明白你的问题。

您想这样做jsfiddle

<form name="ExampleForm" id="ExampleForm">
  <span simple="{{val}}">{{val}} - value from data-binding </span>
  <br>
  <span simple="valueTwo">valueTwo - hard code value</span>
</form>

和js控制器

.controller('ExampleController', function($scope, $rootScope, $alert) {
$scope.val = "valueOne";})

和js指令

.directive('simple', function() {
return {
  restrinct: 'A',
  scope: {
    simple: "@"
  },
  link: function(scope) {
    console.log(scope.simple, typeof(scope.simple));
  }
}})

<强>已更新

angular.module('ExampleApp', ['use', 'ngMessages'])
  .controller('ExampleOneController', function($scope) {
    $scope.val = "valueOne";
    $scope.$on('pass.from.directive', function(event, value) {
      $scope.valFromDirective = value;
    });
  })
  .controller('ExampleTwoController', function($scope) {
    $scope.val = "valueTwo";
    $scope.$on('pass.from.directive', function(event, value) {
      $scope.valFromDirective = value;
    });
  })
  .controller('ExampleThreeController', function($scope) {
    $scope.val = "valueThree";
    $scope.$on('pass.from.directive', function(event, value) {
      $scope.valFromDirective = value;
    });
  })
  .directive('simple', function($interval) {
    return {
      restrinct: 'A',
      scope: {
        simple: "@"
      },
      link: function(scope) {
        var i = 0;
        $interval(function() {
          i++;
          scope.$emit('pass.from.directive', scope.simple + i);
        }, 1000);

      }
    }
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular-messages.min.js"></script>
<script src="https://cdn.rawgit.com/Stepan-Kasyanenko/use-form-error/master/src/use-form-error.js"></script>

<div ng-app="ExampleApp">
  <div ng-controller="ExampleOneController">
    <h3>
      ExampleOneController
    </h3>
    <form name="ExampleForm" id="ExampleForm">
      <div simple="{{val}}">{{val}} - value from scope </div>
      <div>{{valFromDirective}} - value from directive </div>
    </form>
  </div>
  <div ng-controller="ExampleTwoController">
    <h3>
      ExampleTwoController
    </h3>
    <form name="ExampleForm" id="ExampleForm">
      <div simple="{{val}}">{{val}} - value from scope </div>
      <div>{{valFromDirective}} - value from directive </div>
    </form>
  </div>
    <div ng-controller="ExampleThreeController">
    <h3>
      ExampleThreeController
    </h3>
    <form name="ExampleForm" id="ExampleForm">
      <div simple="{{val}}">{{val}} - value from scope </div>
      <div>{{valFromDirective}} - value from directive </div>
    </form>
  </div>
</div>