【问题标题】:AngularJS custom directive - map isolate scope to new child scopeAngularJS 自定义指令 - 将隔离范围映射到新的子范围
【发布时间】:2016-02-05 06:42:32
【问题描述】:

我为引导警报创建了一个自定义指令。我的警报显示正常(硬代码和数据绑定)。根据警报类型,我想根据返回的范围值(成功、信息、警告、危险)在警报消息中显示一个唯一的标题。目前我将类型传递给<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>

在我的指令中,使用范围隔离范围:'@'(单向)

.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) {}
    }
});

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

我该如何解决这个问题?

【问题讨论】:

  • 你的意思是说,你想在type="Something"这样的硬编码字符串中传递type值?
  • 是的,类型可以硬编码 type="string"。但只有 4 个可接受的值。
  • 所以你可以直接从attributes读出值,你不需要费心在隔离范围内传递它..如果它不会动态出现
  • 或通过数据绑定,首选方法,仅取决于应用程序。也许我只需要只允许数据绑定选项。然后我可以从单个数据源数组中执行 {{alert.type}} 和 {{alert.heading}}
  • 挑战是我试图在单个自定义指令中同时做到这两点

标签: angularjs angularjs-scope


【解决方案1】:

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

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 属性是否存在并调用dismiss 处理程序或直接关闭警报。

DEMO PLNKR 显示了与ng-repeat 指令一起使用的指令以及以独立方式使用的指令。

【讨论】:

    【解决方案2】:

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

    你想这样做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>

    【讨论】:

    • 我认为我没有很好地解释我的问题。将数据绑定和硬编码值一起使用没有问题。基于从隔离范围传递的值,我需要在指令中创建一个新值,我可以将其填充到新的 VAR 中。示例:成功 = header1、info = header2 等
    • 我想,我明白了。尝试event 角度$emit 方法。从$scope 传递你的价值,就像这样&amp;scope.$emit ('value.pass',yourValue),然后在你的$scope 像这样$scope.$on ('value.pass',function (event, value,){$scope[value.field].value.val}) 收听。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多