Skip to content

Feature request: View defined filter #1393

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

Closed
georeith opened this issue Sep 23, 2014 · 5 comments
Closed

Feature request: View defined filter #1393

georeith opened this issue Sep 23, 2014 · 5 comments

Comments

@georeith
Copy link

I currently have use case for this and was thinking that other developers may find it useful.

I would like to see a filter that can be used in directives such as ng-if, ng-switch, ng-show, .etc

The filter checks whether the named view is defined in the current state. Currently you can do something like ng-if="$state.current.views.header", however this required additional checks for absolutely named views, views described in parent states, .etc

I would rather do something like ng-if="'header' | viewInState" which would be true when the view has a template at the current state (and it's progeny).

This is useful in cases where you have supporting elements around a view but want to limit what the view can alter, for example consider the following header:

<header ng-if="'header' | viewInState">
    <span>Brought to you by:</span>
    <span ui-view="header"></span>
</header>

Which a state can modify the second span but not the one next to it, perhaps I would like to conditionally show this entire header only if it's contained view is visible.

The filter would work the same way as view targeting already does where 'header' refers to the ui-view only within the scope of the current view (based on filter's location) and header@wizard refers to the header view on the wizard state.

@ProLoser
Copy link
Member

Couldn't you put the <span>Brought to you by:</span> inside the header view?

@ProLoser
Copy link
Member

I feel like this is kind of a step in the wrong direction since the conditionality of a view is part of the view tag itself. I think you're going to end up shooting yourself in the foot if you tie all this logic to wether or not the view tag is populated. Like what if you change your state tree structure, all this conditional logic is going to break. It seems like it's too much knowledge of the entire state tree (or maybe it's just me).

@georeith
Copy link
Author

@ProLoser That is just a simple example, the point is that I have an area in this state that I only want to be visible when the view is populated, and I have child states (or ancestors) that can fill the view. Say I want to animate the entering of views but not the static content around it?

It conforms to DRY, I do not have to repeat this area in all my templates. Say I have some directives I don't in there that I don't want to be recompiled.

If I change my state tree nothing unexpected would happen, if that view is populated it shows if it doesn't it doesn't. Surely I would of changed my state tree to populate the views I want to populate thus I wouldn't be surprised by the results.

I disagree that it is the wrong direction, I think that recompiling the unnecessary template areas is wasteful, repeating the section in multiple templates makes maintenance worse. Whereas this keeps it all in one place.

The use case I have specifically here is for a wizard in a modal, the modal defines a header, content and footer, the modal has multiple views that can be animated between but fixed items in the header if it is defined. The modals are animated, I don't want to animate the static content in the header or have to repeat it in every child template of the modal (what if I want to change it later?).

@christopherthielen
Copy link
Contributor

This reminds me of #1282. @georeith something smells wrong in the way you're approaching this. That said, I think the 1.0.0 Transition object will expose the views being activated, so you would be able to roll your own functionality then.

I think with existing ui-router you can achieve this in a few different ways....

  1. Another named view which gets targetted at the same time you target the header view:
<header>
  <span ui-view="maybeheadermessage"><!-- default content (a comment) when no view is loaded here --></span>
  <span ui-view="header"></span>
</header>
state({ name: 'modal.state1', views: { 
  header: { template: '<h1>state1 header</h1>' }
};

state({ name: 'state2', views: { 
  header: { template: '<h1>state2 header</h1>' },
  maybeheadermessage: { template: '<b>Custom message for state2</b>' }
};

state({ name: 'state3', views: { 
  header: { template: '<h1>state3 header</h1>' },
  maybeheadermessage: { templateUrl: 'standardMaybeMessage.html' }
};

state({ name: 'state4', views: { 
  header: { template: '<h1>state4 header</h1>' },
  maybeheadermessage: { templateUrl: 'standardMaybeMessage.html' }
};
  1. If that's too much code for you, you can use the inherited 'data' object like so:
<header ng-if="$state.current.data.hasheaderview">
  <span>brought to you by</span>
  <span ui-view="header"></span>
</header>
state({ name: 'modal.state1', views: { 
  header: { template: '<h1>state1 header</h1>' }
}});

state({ name: 'state2', views: { 
  header: { template: '<h1>state2 header</h1>' },
  data: { hasheaderview: true }
}});

state({ name: 'state3', views: { 
  header: { template: '<h1>state3 header</h1>' },
  data: { hasheaderview: true }
}});

state({ name: 'state4', views: { 
  header: { template: '<h1>state4 header</h1>' },
  data: { hasheaderview: true }
}});

@eddiemonge
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants