-
Notifications
You must be signed in to change notification settings - Fork 26.1k
feature: support multiple case matching in ngSwitch
/@switch
#14659
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@peterhe2000 I support you. I am building an angular application like the below.
In angular1, I can do this:
But, there's no "ng-switch-when-seprartor" feature like in angular2
for now, the solution is:
|
@kanlidy You solution may not work according to #12174. |
I'd also love that feature, since plain switch case in every language provide that functionality. |
Hi, I'm also interested in this! I also just had the thought of borrowing the new <div [ngSwitch]="data.type">
<div *ngSwitchCase="'multi-choice'; do form1"></div>
<div *ngSwitchCase="'singe-choice'; do form1"></div>
<ng-template #form1>FORM 1</ng-template>
<div *ngSwitchCase="'range'">FORM 2</div>
</div> Additionally, it allows for some other neat things that you can do with |
any progress on this ? |
I'd like to see this too, I was surprised that angular does not offer this functionality, since it is one of the basic functionalities of switch statements in most languages. EDIT: Oh wait, then I'll have to use a crazy nested construction of else blocks to replace the default case :( |
Would it be sufficient to replace: _matchCase(value: any): boolean {
const matched = value == this._ngSwitch; with: _matchCase(value: any): boolean {
const matched = value == this._ngSwitch
|| (value instanceof Array && value.some(x => x == value)); in packages/common/src/directives/ng_switch.ts I guess it isn't that simple. In the meantime I'm going to try the boolean evaluation trick mentioned by @kanlidy, thanks for that. |
+1 on this |
I don't mind the Anything else requires a separator, the best I could think of was Another option could be defining the cases in child elements, e.g.: <div [ngSwitch]="data.type">
<div *ngSwitchMultiple>
<ng-switch-case value="'multi-choice'"></ng-switch-case>
<ng-switch-case value="'single-choice'"></ng-switch-case>
FORM 1
</div>
<div *ngSwitchCase="'range'">FORM 2</div>
</div> I think in comparison using the |
Relates to #20027 (which is possible while this one is not) |
Yeah I don't think the separator approach is that great of an idea. #20027 also seems reasonable. Also, if anyone following this wants an actual workaround they can do now without having to duplicate code, <div [ngSwitch]="data.type">
<div *ngSwitchCase="'multi-choice'">
<ng-container *ngTemplateOutlet="form1"></ng-container>
</div>
<div *ngSwitchCase="'single-choice'">
<ng-container *ngTemplateOutlet="form1"></ng-container>
</div>
<ng-template #form1>FORM 1</ng-template>
<div *ngSwitchCase="'range'">FORM 2</div>
</div> |
HI, |
@specialkk For now I think this is a good approach. Its not ideal but it works and is what I ended up doing until I just fixed our switch statements to not need this. I would prefer somehow if we could move that template HTML into another file somehow. It feels odd just having your template at the bottom of your html (or wherever) to reference. Another workaround would be this answer which I prefer: https://stackoverflow.com/a/45950368/8678531 |
In order to keep it backwards compatible. Would it be acceptable to have something like the following: <div [ngSwitch]="data.type">
<div *ngSwitchCases="['multi-choice', 'single-choice']">FORM 1</div>
<div *ngSwitchCase="'range'">FORM 2</div>
</div> Notice it's a new directive ngSwitchCases. If someone from the angular team thinks it's a good solution I'm up for making a PR. |
@santialbo I like the sound of that. Implementation should be quite simple as well. |
That's #20027 then. |
@santialbo IMHO it doesn't need to be a new directive. Why not leave it |
What if you would like to match on an array instance ? Doing what you propose would break this use-case. So this needs to be a new directive to clearly indicate that we want to match on multiple values. |
Until this is merged, I created a standalone directive that you can add to your project: https://gist.github.com/jonrimmer/eaabd619e2edeaebed83b7bc68f33daf Use it like this: <div [ngSwitch]="value">
<div *jrSwitchCases="['foo', 'bar']">
Foo or bar
</div>
</div> |
#27421 add the support of array on |
Any progress in this? |
Apparently it's not in A9 either, I'd love to see this feature someday I just had to hack it by doing this:
Hopefully if you end up in this issue it will at least give you a way to do it. |
The PR of @maxigimenez was closed because of the breaking change in the introduced array support. #27421 (comment) Would it be an option to reduce the breaking change by checking if the base value is no array? - const matched = Array.isArray(value) ?
+ const matched = Array.isArray(value) && !Array.isArray(this._ngSwitch) ?
value.indexOf(this._ngSwitch) > -1 : value === this._ngSwitch; |
This feature request is open since 2016 in #43950 and is a very common use case but each time very annoying not to find a pleasing solution for me. Personally I mostly end up using Possible implementations: With or: |
Just to offer some framework cross pollination: Svelte does not currently have a The only reason I find myself on this old I think making In any case, Angular currently has no way to nicely write a view with many different but flat (non-nested) states where some of the states overlap and want to re-use the same template fragment (chunk of code). It's an older framework and I want to be clear I'm NOT just here to talk s**t; this is intended as constructive criticism and I think Angular did a good job at a lot of things but some inevitable missteps were made. I don't know how the Angular team feels about large-scale template language changes vs. 80% fixes via the "standard library" but I do recall from other issues I have written that there is a somewhat-reasonable fear of introducing non-HTML-compliant syntax to templates because that has a good chance of breaking tooling which parses the templates as HTML. Of course, such tooling could be updated to use an Angular-provided parser which handles a superset of HTML. Food for thought. |
Thanks @samclaus - we did indeed when discussing this PR recently talk about the potential for offering more native control flow semantics in templates. This is actually much more achievable now that we have Ivy (and dropped ViewEngine) and would also potentially offer other benefits in type checking etc. That being said this would be a big project, to plan, implement, and roll out, which means that it is unlikely to happen very soon. In the meantime, the expectation is that we will provide an interim improvement to the current directives - probably via a |
@petebacondarwin That's awesome! Sounds like you guys have a good game plan. Of course it will take time. I don't think any serious developers would shame a team for taking a while to implement things cleanly. 😃 |
Any progress on this? it feels really pretty dumb to have to include these kinds of comments in template code: <!--
Why are there 2 <dwpc-key-value-text> instances here?
Because NG cannot handle multiple ngSwitchCase conditions:
https://github.com/angular/angular/issues/14659#issuecomment-959830827
--> |
Ideally something like: @case (1)
@case (2) {
...
} |
Or a list of options
|
ngSwitch
/@switch
Surprised to not see this supported by the new control flow syntax, it's been awaited for over 7 years now 😞 |
Can't believe that this is still not possible |
Can you please give an example of the syntax that works with enums? |
@for (column of props().columns; track $index) {
@switch (column.field) {
@case ('status') {
<td>
<app-badge [props]="{ label: item[column.field] }"/>
</td>
}
@case ('date' || 'createdAt' || 'updatedAt') { // or @case 1 @case 2 @case 3
<td>{{ item[column.field] | date }}</td>
}
@default {
<td>{{ item[column.field] }}</td>
}
}
}``` |
This doesn't work for me. Only the first condition is evaluated. So in my case:
|
Doesn't work. Results in |
Ran into the same issue, wanted to reduce duplicate code.
even with templates it is still a lot of duplication of ng-containers and template outlets/context etc. |
Like what anuglar 1 provide
https://docs.angularjs.org/api/ng/directive/ngSwitch
Also mentioned in here:
#12174
Angular version: 2.4.7
The text was updated successfully, but these errors were encountered: