Y a-t-il un moyen de dire à AngularJS de ne pas afficher le premier élément HTML contenant la directive ng-if. Je veux que Angular affiche uniquement le contenu destiné aux enfants.
Code angulaire:
<div ng-if="checked" id="div1">
<div id="div2">ABC</div>
<div id="div3">KLM</div>
<div id="div4">PQR</div>
</div>
Rendu HTML:
<div id="div1">
<div id="div2">ABC</div>
<div id="div3">KLM</div>
<div id="div4">PQR</div>
</div>
Ce que je veux:
<div id="div2">ABC</div>
<div id="div3">KLM</div>
<div id="div4">PQR</div>
Voici un violon. http://jsfiddle.net/9mgTS/ . Je ne veux pas #div1
en HTML. Je veux juste #div2,3,4
si checked
est true
.
Une solution possible peut être d'ajouter ng-if à tous les éléments enfants, mais je ne souhaite pas le faire.
Il existe une paire de directives non documentées, ng-if-start
et ng-if-end
, que vous pouvez utiliser pour cela. Ils se comportent de manière analogue aux directives ng-repeat-start
ET ng-repeat-end
documentées, et vous pouvez voir les tests unitaires pour eux si vous le souhaitez.
Par exemple, étant donné le code suivant:
<ul>
<li ng-if-start="true">a</li>
<li>b</li>
<li>c</li>
<li ng-if-end>d</li>
<li ng-if-start="false">1</li>
<li>2</li>
<li>3</li>
<li ng-if-end>4</li>
</ul>
les quatre premiers li
s seront affichés et les quatre derniers li
s seront masqués.
Voici un exemple en direct sur CodePen: http://codepen.io/anon/pen/PqEJYV
Il existe également des directives ng-show-start
et ng-show-end
qui fonctionnent exactement comme vous le souhaiteriez.
Si vous souhaitez créer une directive personnalisée, vous pouvez appliquer le programme ng-if aux enfants par programmation et aplatir le DOM dans le processus:
Code de la directive:
.directive('ngBatchIf', function() {
return {
scope: {},
compile: function (Elm, attrs) {
// After flattening, Angular will still have the first element
// bound to the old scope, so we create a temporary marker
// to store it
Elm.prepend('<div style="display: none"></div>');
// Flatten (unwrap) the parent
var children = Elm.children();
Elm.replaceWith(children);
// Add the ng-if to the children
children.attr('ng-if', attrs.ngBatchIf);
return {
post: function postLink(scope, Elm) {
// Now remove the temporary marker
Elm.remove();
}
}
}
}
})
Code angulaire:
<div id="div1" ng-batch-if="checked">
<div id="div2">ABC</div>
<div id="div3">KLM</div>
<div id="div4">PQR</div>
</div>
Rendu HTML:
<div id="div2" ng-if="checked">ABC</div>
<div id="div3" ng-if="checked">KLM</div>
<div id="div4" ng-if="checked">PQR</div>
Fiddle: http://jsfiddle.net/o166xg0s/4/
Je ne comprends pas pourquoi vous ne voulez pas utiliser un div parent, mais ce serait une bonne solution si vous avez +20 divs:
HTML
<div ng-repeat="div in divs" ng-if="checked" id="{{div.name}}">{{div.content}}</div>
JS
app.controller('myCtrl', function($scope) {
$scope.checked = true;
$scope.divs = {
{'name': 'div2', content:'ABC'},
{'name': 'div3', content:'KLM'},
{'name': 'div4', content:'PQR'}
}
});
Voici une solution 1.21 angulaire:
HTML:
<div ng-app="app" ng-controller="ctrl">
<div ng-iff="checked" id="div1">
<div id="div2">ABC</div>
<div id="div3">KLM</div>
<div id="div4">PQR</div>
</div>
<button ng-click="toggleCheck()">Toggle Check</button>
</div>
JAVASCRIPT:
angular.module('app', []).
controller('ctrl', function ($scope) {
$scope.checked = true;
$scope.toggleCheck = function () {
$scope.checked = !$scope.checked;
};
}).
directive('ngIff', function ($compile) {
return {
compile: function compile(tElement, tAttrs, transclude) {
return {
pre: function preLink(scope, iElement, iAttrs, controller) {
var bindingElem = iElement.attr('ng-iff');
var children = iElement.children();
angular.forEach(children,function(c){
angular.element(c).attr('ng-if',bindingElem);
});
$compile(children)(scope, function(newElem){
iElement.replaceWith(newElem);
});
}
};
}
};
});
JSFIDDLE .