javascript - switch - Lógica condicional en la plantilla AngularJS
ng switch angular 6 (3)
Tengo una plantilla angular que se parece a esto ...
<div ng-repeat="message in data.messages" ng-class="message.type">
<div class="info">
<div class="type"></div>
<div class="from">From Avatar</div>
<div class="createdBy">Created By Avatar</div>
<div class="arrowTo">
<div class="arrow"></div>
<div class="to">To Avatar</div>
</div>
<div class="date">
<div class="day">25</div>
<div class="month">Dec</div>
</div>
</div>
<div class="main">
<div class="content">
<div class="heading2">{{message.title}}</div>
<div ng-bind-html="message.content"></div>
</div>
</div>
<br />
<hr />
<br />
</div>
He configurado un JSfiddle para mostrar los datos que se enlazan.
Lo que tengo que hacer es hacer que los divs "desde", "hasta" y "flecha a" se muestren condicionalmente, dependiendo del contenido de los datos.
El registro es este ...
- Si hay un objeto "de" en los datos, muestre el div "de" y vincule los datos pero no muestre el div "createdBy".
- Si no hay un objeto "de" pero hay un objeto "createdBy", entonces muestra el div "createdBy" y vincula los datos.
- Si hay un objeto "to" en los datos, muestre el div "arrowTo" y agréguele los datos.
O en inglés simple, si hay una dirección de, muéstrela, de lo contrario muestre quién creó el registro en su lugar y si hay una dirección a continuación, muéstrela también.
He analizado el uso de ng-switch, pero creo que tendría que agregar un marcado adicional que dejaría un div vacío si no hubiera datos. Además, necesitaría anidar las directivas de cambio y no estoy seguro de si eso funcionaría.
¿Algunas ideas?
ACTUALIZAR:
Si tuviera que escribir mi propia directiva (¡Si supiera cómo!), Aquí hay un pseudo código para mostrar cómo me gustaría usarlo ...
<div ng-if="showFrom()">
From Template Goes Here
</div>
<div ng-if="showCreatedBy()">
CreatedBy Template Goes Here
</div>
<div ng-if="showTo()">
To Template Goes Here
</div>
Cada uno de estos desaparecería si la función / expresión se evalúa como falsa.
Angular 1.1.5 introdujo la directiva ng-if . Esa es la mejor solución para este problema en particular. Si está utilizando una versión anterior de Angular, considere usar la directiva ui-if angular-ui.
Si llegó aquí buscando respuestas a la pregunta general de "lógica condicional en plantillas" también considere:
- 1.1.5 también introdujo un operador ternario
- ng-switch se puede usar para agregar / eliminar condicionalmente elementos del DOM
- ver también ¿Cómo aplico condicionalmente estilos CSS en AngularJS?
Respuesta original:
Aquí hay una no muy buena directiva "ng-if":
myApp.directive(''ngIf'', function() {
return {
link: function(scope, element, attrs) {
if(scope.$eval(attrs.ngIf)) {
// remove ''<div ng-if...></div>''
element.replaceWith(element.children())
} else {
element.replaceWith('' '')
}
}
}
});
que permite esta sintaxis HTML:
<div ng-repeat="message in data.messages" ng-class="message.type">
<hr>
<div ng-if="showFrom(message)">
<div>From: {{message.from.name}}</div>
</div>
<div ng-if="showCreatedBy(message)">
<div>Created by: {{message.createdBy.name}}</div>
</div>
<div ng-if="showTo(message)">
<div>To: {{message.to.name}}</div>
</div>
</div>
Fiddle .
replaceWith () se usa para eliminar contenido innecesario del DOM.
Además, como mencioné en Google+, ng-style probablemente se puede usar para cargar de forma condicional las imágenes de fondo, en caso de que quiera usar ng-show en lugar de una directiva personalizada. (Para el beneficio de otros lectores, Jon declaró en Google+: "ambos métodos usan ng-show que trato de evitar porque usa display: none y deja marcas adicionales en el DOM. Este es un problema particular en este escenario porque el elemento oculto tendrá una imagen de fondo que aún se cargará en la mayoría de los navegadores ").
Consulte también ¿Cómo aplico condicionalmente estilos CSS en AngularJS?
La directiva ui-if vigila los cambios en la condición / expresión if. La mía no. Por lo tanto, si bien mi implementación simple actualizará la vista correctamente si el modelo cambia de modo que solo afecte a la salida de la plantilla, no actualizará la vista correctamente si la respuesta de condición / expresión cambia.
Por ejemplo, si el valor de un nombre de. Cambia en el modelo, la vista se actualizará. Pero si delete $scope.data.messages[0].from
, se eliminará el nombre de la vista, pero la plantilla no se eliminará de la vista porque la condición / expresión if no se está viendo.
Puede usar la directiva ngSwitch :
<div ng-switch on="selection" >
<div ng-switch-when="settings">Settings Div</div>
<span ng-switch-when="home">Home Span</span>
<span ng-switch-default>default</span>
</div>
Si no desea que el DOM se cargue con divs vacíos, debe crear su directiva personalizada utilizando $ http para cargar las (sub) plantillas y $ compile para inyectarla en el DOM cuando haya alcanzado una determinada condición.
Este es solo un ejemplo (no probado). Puede y debe ser optimizado:
HTML:
<conditional-template ng-model="element" template-url1="path/to/partial1" template-url2="path/to/partial2"></div>
Directiva:
app.directive(''conditionalTemplate'', function($http, $compile) {
return {
restrict: ''E'',
require: ''^ngModel'',
link: function(sope, element, attrs, ctrl) {
// get template with $http
// check model via ctrl.$viewValue
// compile with $compile
// replace element with element.replaceWith()
}
};
});
Puede usar ng-show en cada elemento div en el ciclo. Es esto lo que has querido: http://jsfiddle.net/pGwRu/2/ ?
<div class="from" ng-show="message.from">From: {{message.from.name}}</div>