This is old, but I was hunting for this answer and wound up looking up the ngSwitchCase code and creating an array version. Angular uses basically this code to check each ngSwitchCase via the DoCheck & within the ngSwitch a call to _matchCase(value), also noticed the code plays with index counts, so for each item in the array you need to create an object or validate it yourself outside the list. Which is how I created this one.
import { NgSwitch } from '@angular/common';
import {Directive, DoCheck, Host, Input, OnInit, Optional, TemplateRef, ViewContainerRef, ɵRuntimeError as RuntimeError} from '@angular/core';
@Directive({
selector: '[ngSwitchCaseArray]'
})
export class NgSwitchCaseArray implements DoCheck {
private _view: SwitchView;
/**
* Stores the HTML template to be selected on match.
*/
@Input() ngSwitchCaseArray: any[] = [];
constructor(
viewContainer: ViewContainerRef, templateRef: TemplateRef<Object>,
@Optional() @Host() private ngSwitch: NgSwitch) {
if (!ngSwitch) { // make sure we have a host
throwNgSwitchProviderNotFoundError('ngSwitchCaseArray', 'NgSwitchCaseArray');
}
this._view = new SwitchView(viewContainer, templateRef);
// either we add a case for each time we call ngSwitch._matchCase
// or we only add one case and call matchcase once per check
(this.ngSwitch as any)._addCase();
}
// this is how the ngSwitchCase works, just call's ngSwitch._matchCase(item) when true we're supposed to do something
ngDoCheck() {
this._view.enforceState(this.matchCase());
}
matchCase(): boolean {
// advantage of us finding the item in our array, is we're not calling matchCase which requires 1 addCase per call
// so if the array changes it wont break the case code we initialize with
var switchValue = (this.ngSwitch as any)._ngSwitch; // this is the value passed into ngSwitch
var index = this.ngSwitchCaseArray.indexOf(switchValue); // grab index, jic value is null, undefined, etc.
var item: any = this.ngSwitchCaseArray; // pass the array as default, should fail in most cases
if (index != -1) item = this.ngSwitchCaseArray[index]; // get the actual value if we found an index
return (this.ngSwitch as any)._matchCase(item); // MUST call _matchCase once and only once or you break ngSwitch
}
}
// stuff below was copied from angular/packages/common/src/directives/ng_switch.ts
class SwitchView {
private _created = false;
constructor(
private _viewContainerRef: ViewContainerRef, private _templateRef: TemplateRef<Object>) {}
create(): void {
this._created = true;
this._viewContainerRef.createEmbeddedView(this._templateRef);
}
destroy(): void {
this._created = false;
this._viewContainerRef.clear();
}
enforceState(created: boolean) {
if (created && !this._created) {
this.create();
} else if (!created && this._created) {
this.destroy();
}
}
}
function throwNgSwitchProviderNotFoundError(attrName: string, directiveName: string): never {
throw new RuntimeError(
2000, //RuntimeErrorCode.PARENT_NG_SWITCH_NOT_FOUND,
`An element with the "${attrName}" attribute ` +
`(matching the "${
directiveName}" directive) must be located inside an element with the "ngSwitch" attribute ` +
`(matching "NgSwitch" directive)`);
}
Then you just need some code for it to work:
<div *ngSwitch="objectValue">
<div *ngSwitchCase="abc">abc found</div>
<div *ngSwitchCaseArray="[ 'value', 'Value', null, 'Blah', 'etc.' ]">Found something in the array</div>
<div *ngSwitchDefault>Nothing found</div>
</div>