Assign directive attributes to an element in template

I have a directive which is supposed to make my select a little fancier:

angular.module('myDeadLine')

    .directive('dcSelect', function () {
        return {
            restrict: 'E',
            scope: {
                label: '@',
                ngModel: '=',
                ngOptions: '=',...
            },
            transclude: true,
            templateUrl: '/web/_utils/dcselect/dcselect.html'
        };
    });

with the template:

<div class="form-group">
    <select class="form-control"
            ng-focus="dcSelectFocused=true"
            ng-blur="dcSelectFocused=false">
        <option value="">{{label}}</option>
    </select>
    <i class="fa fa-arrow-down" ng-class="{ 'open': dcSelectFocused }"></i>
</div>

What is the easiest way to assign all select related attributes on to the select tag so I can use it like this:

<dc-select label="Select something" ng-model="model" ng-options="" and so on></dc-select>

Is there an automated way by which I can transfer all attributes to select except "label", and have them function?

Answers:

Answer

It is the valid scenario, but the resistance from Angular doesn't make it a trivial task to do. Usually replace: true is used to transfer all the attributes to the child template element. But select isn't a direct descendant, it is not an option.

The other possibility is to use terminal: true in conjunction with high priority, because ng-model, ng-options and any other attribute directives shouldn't be compiled on dc-select element. But terminal: true would also stop the bindings from working (in this case they have to be interpolated manually).

I guess the easiest way is

.directive('dcSelect', function ($compile) {
    return {
        restrict: 'E',
        scope: {
            label: '@',
            dcNgModel: '=',
            dcNgOptions: '='
        },
        transclude: true,
        templateUrl: '/web/_utils/dcselect/dcselect.html',
        link: function (scope, element, attrs) {
          var select = element.find('select');

          angular.forEach(attrs.$attr, function (name, normalizedName)  {
            if (!name.match(/^dc-/)) return;

            var val = scope.hasOwnProperty(normalizedName) ? normalizedName : element.attr(name);
            select.attr(name.replace(/^dc-/, ''), val);
          });

          $compile(select)(scope);
        }
    };
});

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.