#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
Короче говоря, интерполированные атрибуты устанавливаются после цикла дайджеста, и это перезаписывало мое значение по умолчанию.