问题
So I have two elements that are exclusive:
<span>foo</span>
<span>bar</span>
And I added ngShow and ngHide to them:
<span ng-show="fooTime">foo</span>
<span ng-hide="fooTime">bar</span>
But now when these render, there is a split second where they both show.
How can I make them show/hide at the same time?
回答1:
Use a ngSwitch rather than an ngShow/ngHide:
<span ng-switch="fooTime">
<span ng-switch-when="true">foo</span>
<span ng-switch-when="false">bar</span>
</span>
Why?
When using the separate ngShow/ngHides, each element is getting a separate $watch which execute asynchronously leaving the potential for a gap between the events. By using ngSwitch, only one $watch is setup so they must render at the same time.
How I got to ngSwitch?
On my first attempt, I realized the watches were not tied together, so I resorted to letting CSS tie the changes together:
<style>
[first] .fooTime {
display: inline;
}
[second] .fooTime, [first] {
display: none;
}
</style>
<span ng-class="{'fooTime':fooTime}">
<span first>foo</span>
<span second>bar</span>
</span>
But ngSwitch is much more clean.
Edit: It seems ngSwitch triggers enter and leave animations so if you are using ngAnimate, there is a default of a .2 second transition. I haven't found a way around this yet.
回答2:
Upvoted and commented on @eternalmatt's answer ... here is my solution based on the css
part of his solution. In my experience ng-swtich
will not solve this problem. I am using scss
but you can convert scss
to css
here http://www.sassmeister.com/. The template of my button directive that toggles button text and ajax spinner based on the value of showSpinner
.
template
<button class="fin-button no-outline" ng-class="{disabled: state==='disabled'}" ng-click="action()">
<span ng-class="{'showSpinner': showSpinner}">
<span class="text-first" fin-button-text>{{text}}</span>
<span class="glyphicon glyphicon-repeat spinner" fin-button-spinner></span>
</span>
</button>
scss
.fin-button {
[fin-button-text] {
display: inline;
}
[fin-button-spinner] {
display: none
}
.showSpinner {
[fin-button-text] {
display: none;
}
[fin-button-spinner] {
display: inline;
}
}
}
css .. generated from conversion via the above link
.fin-button [fin-button-text] {
display: inline;
}
.fin-button [fin-button-spinner] {
display: none;
}
.fin-button .showSpinner [fin-button-text] {
display: none;
}
.fin-button .showSpinner [fin-button-spinner] {
display: inline;
}
and is here be dragons
comment that I have above the scss in my code
// .... HERE BE DRAGONS ... ///
// The following is used to hide show the spinner or the
// button text. Needs to be done like this because ng-hide, ng-show,
// ng-if, and ng-switch all put seperate watches even if you are conditioning
// on the same vairable ... see this SO // http://stackoverflow.com/questions/20341288/how-do-i-ngshow-and-nghide-two-different-elements-at-the-same-time-with-angularj
来源:https://stackoverflow.com/questions/20341288/how-do-i-ngshow-and-nghide-two-different-elements-at-the-same-time-with-angularj