присвойте значения по умолчанию необязательным атрибутам в директиве в angularjs

#angularjs #angularjs-directive

#angularjs #angularjs-директива

Вопрос:

Я пытаюсь присвоить значения по умолчанию директиве, которая имеет необязательные атрибуты. Я даю значения по умолчанию в методе scope.init(), показанном ниже. Я не вижу, чтобы мои значения по умолчанию отражались в представлении. Если я попытаюсь выполнить scope.$apply() , он скажет, что он уже переваривается 🙂 Что я делаю не так?

 angular.module('noi.questionOptions', ['noi.filters'
  //'ui.bootstrap'
]).directive('noiQuestionOptions', ['$filter', '$log', function($filter, $log){
    'use strict';

    var letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
    var romans = ['i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix','x'];
    return {
        restrict: 'EA',
        scope: {
            // have .text attribute and optionall index 
            options: "=noiOptions",
            // default ) 
            separator: '@?noiSeparator',
            // one of alpha, numeric, roman, defaults to numeric
            indexType: '@?noiIndexType',
            // vertical or horizaontal, default horizontal
            orientation: '@?noiOrientation',
            // upper or lower, default upper
            indexCase: '@?noiIndexCase'
        },
        templateUrl: 'noi.questionOptions.html',
        controller: function($scope, $element, $attrs){
            var scope = $scope;            
            scope.isIndexUpper = function(){
                return scope.indexCase == 'lower' ? false : true;
            };
            scope.isHorizontal = function(){
                return scope.orientation == 'vertical' ? false : true;
            };
            scope.init = function(){
                if (!angular.isDefined($scope.indexCase)) {
                    $scope.indexCase = 'upper';               
                };

                if (!angular.isDefined($scope.separator)) {
                    $scope.separator = '.';
                    //scope.separator = ')';
                }

                if (!angular.isArray($scope.options)) {
                    //$log.log('not array');
                    return;
                }
                angular.forEach($scope.options, function(opt, i){
                    if (angular.isDefined(opt.index)) {
                        //return;
                    }                    
                    if ($scope.indexType == 'roman') {
                        opt.index = romans[i];
                    } else if ($scope.indexType == 'alpha') {
                        opt.index = letters[i];
                    } else {
                        opt.index = i;
                    }                    
                });
            };
            scope.init();
            //$log.log("aaa"   scope.options); 

            $log.log(scope.options);
            //scope.$apply();
        },
        link: function(scope, element, attrs) {



        }
    };
}]);
 

Вот шаблон

 <ul class="list-unstyled " ng-class="{'list-inline':isHorizontal()}">
    <li ng-repeat="opt in options"> {{opt}}
        <span ng-class="{'text-uppercase':isIndexUpper(), 'text-lowercase':!isIndexUpper()}"
              >{{opt.index}} {{ separator}}</span> {{opt.text}}
    </li>
</ul>
{{separator}} - {{indexType}} - {{orientation}} - {{indexCase}} - {{options}}  
 

эти выражения ниже /ul (кроме {{options}}) ничего не показывают. {{options}} не показывает атрибут .index, который я добавляю в цикле forEach выше. Однако я вижу на консоли, что параметры имеют атрибуты .index

— фактический файл js шаблона — (нет проблем с загрузкой шаблона)

 angular.module('erdal').run(['$templateCache', function($templateCache) {
  'use strict';

  $templateCache.put('noi.questionOptions.html',
    "<ul class="list-unstyled" ng-class="{'list-inline':isHorizontal()}"><li ng-repeat="opt in options">{{opt}} <span ng-class="{'text-uppercase':isIndexUpper(), 'text-lowercase':!isIndexUpper()}">{{opt.index}} {{ separator}}</span> {{opt.text}}</li></ul>{{separator}} - {{indexType}} - {{orientation}} - {{indexCase}} - {{options}}"
  );

}]);
 

Это dom, который включает директиву

 <div data-noi-question-options     
     noi-options="[{text:'ankara'}, {text:'Istanbul'}, {text:'Antalya'}, {text:'Izmir'}]" 
                 ></div>
 

Комментарии:

1. Можете ли вы обновить свой код, чтобы шаблон включал директиву ‘noiQuestionOptions’? Я подозреваю, что ваш список ниже UL не входит в сферу действия директивы ‘noiQuestionOptions’.

2. К какой области DOM применяется директива? Вы не указали это в своем шаблоне выше.

3. Этот шаблон введен, проблем с загрузкой шаблона нет. Я добавляю версию шаблона javascript по мере его добавления (с помощью grunt)

4. Не могли бы вы попробовать обернуть свой шаблон в <div></div> ? Вероятно, ваша область действия изолирована от первого элемента DOM.

5. Возможно, он не связан с родительской областью из-за того, что он не существовал во время связывания директивы. Значит, он создается только как область действия локальной директивы, но не попадает в атрибут?

Ответ №1:

Я удалил всю scope.init() … и заменил его на эти

 scope.$watch('indexType', function(newVal, oldVal, scope){
        //console.log(newVal   ' '   oldVal);
        if (!angular.isDefined(newVal)){
            scope.indexType = 'upper';
        }
    });
    scope.$watch('separator', function(newVal, oldVal, scope){
        //console.log(newVal   ' '   oldVal);
        if (!angular.isDefined(newVal)){
            scope.separator = ')';
        }
    });

    scope.$watch('options', function(newVal, oldVal, scope){
        if (!angular.isArray(scope.options)) {
            //$log.log('not array');
            return;
        }
        angular.forEach(scope.options, function(opt, i){
            if (angular.isDefined(opt.index)) {
                return;
            }                    
            if (scope.indexType == 'roman') {
                opt.index = romans[i];
            } else if (scope.indexType == 'alpha') {
                opt.index = letters[i];
            } else {
                opt.index = i;
            }                    
        });
    });
 

Очень хорошее объяснение на этой странице о той же проблеме .. https://groups.google.com/forum /#!сообщение/angular/lA2oXI8-PdY/N-0dAQ4c1G4J

Короче говоря, интерполированные атрибуты устанавливаются после цикла дайджеста, и это перезаписывало мое значение по умолчанию.