在Angular中将attrs作为$ scope变量传递

时间:2014-06-27 21:13:42

标签: javascript angularjs angularjs-directive

我有一个指令,我正在尝试获取Attrs并将它们传递给$ scope,但我不太清楚如何做到这一点。更具体地说,我正在尝试将模板中的属性设置为等于我的日期选择器标记中的名称。我尝试将它们设置为变量,但显然这不起作用。 非常感谢帮助和进一步澄清。谢谢!

HTML

<date-picker id="dateendPicker" name="date_end"></date-picker>

JS

App.directive('datePicker', function(){
  return {
  scope: {
          name : '@'
         },
  restrict: 'AE',
  replace: 'true',
  template: '<div class="date"><div class="input-group"><input type="text" class="form-control" id="{{this_name}}" name="{{this_name}}" ng-model="event.{{this_name}}" required/><span class="input-group-addon"><i class="fa fa-calendar"></i></span></div></div>',
  controller: ['$scope', function($scope){
        $scope.this_name = this_name;
  }],
  link: function(scope, element, attrs){
    var this_name = attrs.name;
  }
  }
});

3 个答案:

答案 0 :(得分:2)

由于您如何定义指令范围:

  scope: {
      name : '@'
  }

name已经是您作用域的变量。如果您在控制器\链接功能上没有做任何特殊操作,可以完全删除它们,并在模板中使用{{name}}引用它。请注意,如果您使用'@'创建范围绑定,那么在您的html中,您应该将数据作为角度表达式传递,这意味着:

name="{{date_end}}"

答案 1 :(得分:0)

正如我从您的代码段中看到的那样,您希望将name属性用作ng-model into指令。我认为,您应该考虑使用其他类型的隔离范围(related SO answer

这是我的方法(jsFiddle):

app.directive('datePicker', function () {
    return {
        scope: {
            name: '=name'
        },
        restrict: 'AE',
        replace: 'true',
        template: 
            '<div class="date">' +
                '<div class="input-group">' +
                    '<input type="text" ' +
                            'class="form-control" ' +
                            'id="bad-idea-to-make-it-editable-id" ' +
                            'name="{{ name }}" ' +
                            'ng-model="name" ' +
                            'required/>' +
                    '<span class="input-group-addon">' +
                        '<i class="fa fa-calendar"></i>' +
                    '</span>' +
                '</div>' +
            '</div>'
        }
    });

现在您可以从指令编辑父作用域。但是,如果您不希望在范围之间进行此类通信,请使用@范围,作为@haimlit has mentioned

答案 2 :(得分:0)

您的代码段存在一些问题: 首先,您不要将attrs分配给scope,而是分配给局部变量,因此它不会在控制器功能中可用。

你可以试试这个:

App.directive('datePicker', function(){
    return {
        scope: {
            name : '@'
        },
        restrict: 'AE',
        replace: 'true',
        template: '<div class="date"><div class="input-group"><input type="text" class="form-control" id="{{this_name}}" name="{{this_name}}" ng-model="event.{{this_name}}" required/><span class="input-group-addon"><i class="fa fa-calendar"></i></span></div></div>',
        controller: ['$scope', function($scope){
            $scope.this_name = this_name;
        }],
        link: function(scope, element, attrs){
            scope.this_name = attrs.name;
        }
    }
});

我不知道这是否真的有效,因为不建议同时使用控制器和链接功能(取自directive guide):

  

最佳实践:当您希望将API公开给其他指令时,请使用控制器。否则使用链接。

但根据docs,attrs也可以$attrs作为控制器功能使用:

App.directive('datePicker', function(){
    return {
        scope: {
            name : '@'
        },
        restrict: 'AE',
        replace: 'true',
        template: '<div class="date"><div class="input-group"><input type="text" class="form-control" id="{{this_name}}" name="{{this_name}}" ng-model="event.{{this_name}}" required/><span class="input-group-addon"><i class="fa fa-calendar"></i></span></div></div>',
        controller: ['$scope', '$attrs', function($scope, $attrs){
            $scope.this_name = $attrs.name;
        }]
    }
});

但是你已经在隔离范围中定义了name,因此在conroller或link函数中它应该是scope.name

App.directive('datePicker', function(){
    return {
        scope: {
            name : '@'
        },
        restrict: 'AE',
        replace: 'true',
        template: '<div class="date"><div class="input-group"><input type="text" class="form-control" id="{{this_name}}" name="{{this_name}}" ng-model="event.{{this_name}}" required/><span class="input-group-addon"><i class="fa fa-calendar"></i></span></div></div>',
        link: function(scope, element, attrs){
            console.log(scope.name); // this is your name defined as attribute name="..." on the tag
        }
    }
});