【问题标题】:Angularjs - Pass argument to directiveAngularjs - 将参数传递给指令
【发布时间】:2014-10-16 16:31:47
【问题描述】:

我想知道是否有办法将参数传递给指令?

我想要做的是从控制器中附加一个指令,如下所示:

$scope.title = "title";
$scope.title2 = "title2";

angular.element(document.getElementById('wrapper')).append('<directive_name></directive_name>');

是否可以同时传递一个参数,以便我的指令模板的内容可以链接到一个或另一个范围?

这里是指令:

app.directive("directive_name", function(){
    return {
        restrict:'E',
        transclude:true,
        template:'<div class="title"><h2>{{title}}</h3></div>',
        replace:true
    };
})

如果我想使用相同的指令但使用 $scope.title2 怎么办?

【问题讨论】:

    标签: angularjs controller arguments directive


    【解决方案1】:

    您可以像使用内置 Angular-directives 一样将参数传递给自定义指令 - 通过在指令元素上指定一个属性:

    angular.element(document.getElementById('wrapper'))
           .append('<directive-name title="title2"></directive-name>');
    

    您需要做的是在指令的工厂函数中定义scope(包括参数/参数)。在下面的示例中,该指令采用 title 参数。然后您可以使用它,例如在 template 中,使用常规的 Angular 方式:{{title}}

    app.directive('directiveName', function(){
       return {
          restrict:'E',
          scope: {
             title: '@'
          },
          template:'<div class="title"><h2>{{title}}</h2></div>'
       };
    });
    

    根据您要绑定的方式/内容,您有不同的选择:

    • = 是双向绑定
    • @ 只是读取值(单向绑定)
    • &amp; 用于绑定函数

    在某些情况下,您可能希望使用不同于“内部”名称的“外部”名称。外部是指指令元素上的属性名称,内部是指在指令范围内使用的变量的名称。

    例如,如果我们查看上述指令,您可能不想为标题指定另一个附加属性,即使您在内部希望使用title-property。相反,您希望按如下方式使用指令:

    <directive-name="title2"></directive-name>
    

    这可以通过在范围定义中在上述选项后面指定一个名称来实现:

    scope: {
        title: '@directiveName'
    }
    

    还请注意以下事项:

    • HTML5 规范规定自定义属性(这基本上是 Angular 应用程序中到处都是)应该以 data- 为前缀。 Angular 通过从任何属性中剥离 data--前缀来支持这一点。因此,在上面的示例中,您可以在元素 (data-title="title2") 上指定属性,内部一切都将是相同的。
    • 元素上的属性始终采用&lt;div data-my-attribute="..." /&gt; 的形式,而在代码中(例如范围对象上的属性)它们采用myAttribute 的形式。在我意识到这一点之前,我浪费了很多时间。
    • 对于在不同 Angular 组件(控制器、指令)之间交换/共享数据的另一种方法,您可能需要查看服务或指令控制器。
    • 您可以在Angular homepage (directives) 上找到更多信息

    【讨论】:

    • 很好的答案,这解释了很多。
    • @ 复制值,对于单向绑定有&lt;&lt;directive-name="title2"&gt;? O.o 这合法吗?
    【解决方案2】:

    这是我解决问题的方法:

    指令

    app.directive("directive_name", function(){
        return {
            restrict: 'E',
            transclude: true,
            template: function(elem, attr){
               return '<div><h2>{{'+attr.scope+'}}</h2></div>';
            },
            replace: true
        };
    })
    

    控制器

    $scope.building = function(data){
        var chart = angular.element(document.createElement('directive_name'));
        chart.attr('scope', data);
        $compile(chart)($scope);
        angular.element(document.getElementById('wrapper')).append(chart);
      }
    

    我现在可以通过同一个指令使用不同的作用域并动态附加它们。

    【讨论】:

    • 你能解释一下吗?
    • 限制指令怎么样:意义属性
    • @eranotzap 它限制指令只能用作属性
    • @Aivus 这是非常正确的。我提到了它们被限制用作属性的答案情况。
    【解决方案3】:

    您可以尝试如下:

    app.directive("directive_name", function(){
    return {
        restrict:'E',
        transclude:true,
        template:'<div class="title"><h2>{{title}}</h3></div>',
        scope:{
          accept:"="
        },
        replace:true
      };
    })
    

    它在 'accept' 属性的值和父作用域之间建立了双向绑定。

    您还可以使用属性设置两种方式的数据绑定:'='

    例如,如果您希望键和值都绑定到本地范围,您可以这样做:

      scope:{
        key:'=',
        value:'='
      },
    

    欲了解更多信息, https://docs.angularjs.org/guide/directive

    所以,如果你想将一个参数从控制器传递给指令,那么请参考下面的小提琴

    http://jsfiddle.net/jaimem/y85Ft/7/

    希望对你有帮助..

    【讨论】:

    • 我不确定我应该如何从控制器传递参数
    • 我已经用小提琴更新了一个答案,请参考它并希望它能给一些想法..
    • 我发现了一些不同的工作方式(更新了我的问题)谢谢!
    • 适用于标量参数,但不适用于对象、数组或函数。 ://
    【解决方案4】:

    控制器代码

    myApp.controller('mainController', ['$scope', '$log', function($scope, $log) {
        $scope.person = {
            name:"sangeetha PH",
           address:"first Block"
        }
    }]);
    

    指令代码

    myApp.directive('searchResult',function(){
       return{
           restrict:'AECM',
           templateUrl:'directives/search.html',
           replace: true,
           scope:{
               personName:"@",
               personAddress:"@"
           }
       } 
    });
    

    用法

    文件:directives/search.html
    内容:

    <h1>{{personName}} </h1>
    <h2>{{personAddress}}</h2>
    

    我们使用指令的文件

    <search-result person-name="{{person.name}}" person-address="{{person.address}}"></search-result>
    

    【讨论】:

      【解决方案5】:
      <button my-directive="push">Push to Go</button>
      
      app.directive("myDirective", function() {
          return {
              restrict : "A",
               link: function(scope, elm, attrs) {
                      elm.bind('click', function(event) {
      
                          alert("You pressed button: " + event.target.getAttribute('my-directive'));
                      });
              }
          };
      });
      

      这就是我所做的

      我使用指令作为 html 属性,并在我的 HTML 文件中传递了如下参数。 my-directive="push" 从指令中我从鼠标单击事件对象中检索到它。 event.target.getAttribute('my-directive').

      【讨论】:

        【解决方案6】:

        在 click 事件中插入 var msg with scope.$apply 以根据控制器对 ng-confirm-click 中显示的变量的更改对确认进行更改。

        <button type="button" class="btn" ng-confirm-click="You are about to send {{quantity}} of {{thing}} selected? Confirm with OK" confirmed-click="youraction(id)" aria-describedby="passwordHelpBlock">Send</button>
        
        
        
        
        app.directive('ngConfirmClick', [
          function() {
            return {
              link: function(scope, element, attr) {
                var clickAction = attr.confirmedClick;
                element.on('click', function(event) {
                  var msg = attr.ngConfirmClick || "Are you sure? Click OK to confirm.";
                  if (window.confirm(msg)) {
                    scope.$apply(clickAction)
                  }
                });
              }
            };
          }
        ])
        

        【讨论】: