Cached views cause IDs and form element names to clash

Ionic likes to keep views that you’ve passed through on your way through a flow as hidden elements on the page. I can still see all the ng-components (or whatever the selector for the ionic page was) in the DOM. The problem with this is if you revisit a page during a flow. I have a flow that goes A > B > C > D > C > D. See the circular structure at the end? I don’t want to POP the nav back to this page, as it receives a new model and operates on new objects. But the problem is, earlier versions of the page are still in the DOM which causes all the form element name attributes and IDs to duplicate and radio buttons and the like stop working properly.

What should I do about this?

Redesign your app so that page D doesn’t care whether it’s been reanimated or newly instantiated.

This is a larger problem than that. The page doesn’t care either way. The problem is html5 components or anything with names/IDs need to be dynamically generated with some high level incrementing variable (similar to the way ionic radio group and buttons work). Ionic has a lot of useful things built in to help deal with idiosyncrasies across phones, but if you want to use those features but make it look like your own design, it’s a real PITA. Because of this, there are some components that just have to be custom and it’s easier sometimes to use HTML 5 components. But not when Ionic has no good way of handling the fact that there may be a page in the history (and in the DOM) that duplicates these and their associated names/IDs and causing all kinds of problems. I shouldn’t have to create a component for a simple radio group just so I can have an incrementing ID counter (because then I have to jump through even more hoops like making ngModel work on the custom component by implementing the Ng access tokens.

It seems like an impossible thing to ask of a framework to be able to know how to manage elements that you are stuffing into the DOM behind its back.

I don’t think it’s much to ask to work how angular works by default. Views are deconstructed after leaving. Especially in a native compiled app where all files are local, the slight gain of having the previous pages all in the DOM does not offset the memory overhead of preserving a ton of views, and the drawbacks of forcing everyone to painstakingly override layers and layers of terrible styling and nesting choices.

Or at least the option to configure it this way, which I can’t seem to find.

Sounds like maybe you would be happier with angular-cli and cordova so that you don’t have to spend so much effort undoing choices Ionic made that you don’t like.

I don’t doubt that. But this is what was chosen for the project by people other than myself, and I’ve found 50% of my time has been creating ways around Ionic and custom components. It would be nice to just be able to turn off the view preservation of your history. That would solve the problem for me.

By design, Ionic pages stay in memory until they are popped off the nav stack. You can physically go into the nav stack and destroy pages, but it sounds as though you want to keep the previous page, and also have a sibling page closer to the top of the stack.

Can you solve your problem in ten minutes of work by copypasting and creating pages C1 and C2 and D1 and D2? That would be a lot less error prone than playing around with the nav stack.

I don’t use ngOnDestroy() at all, just FYI. I act as though it’s unsupported, because it behaves very differently in Ionic land. The basic issue is that native device navigation behaves differently from desktop navigation, and Ionic’s goal was to reproduce a native experience. So they met with the Angular team and came up with an alternative routing system that would feel more native. It is better for phones (IMO) but loses some fancy under-the-hood techniques, which is what you’re running into.

I didn’t describe it perfectly but the circular structure is truly circular (you can visit more than twice). It’s a summary page where you can go back and add more objects, each which proceed back to summary where you can add another.

I’m just going to have to end up implementing a completely custom component for the main culprit which are fancy iconified radio buttons, which until now I was simply just using hidden html5 components and some other elements with classes. I’ll have to have the component generate unique names and IDs for the buttons in order for the labels to continue having the correct for= and the radio buttons to be grouped properly without names overlapping when visiting a previously visited page. (and yes, this is easier than changing the styling of the ionic radio buttons. Their DOM structure and styling is far too rigid and difficult to override).