admin管理员组文章数量:1415467
I have the following AngularJS (v1.1.4) code and am trying to fade-in (animate) the ng-include when it is added to the DOM. What am I doing wrong? Also, if anyone can suggest a better way of passing add/set/remove mands to the directive rather than watching the 'action' property, that would be much appreciated.
Plunker is here:
index.html
<!doctype html>
<html ng-app="plunker" >
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="styles.css" />
<script>document.write('<base href="' + document.location + '" />');</script>
<script src=".1.4/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<button ng-click="loadPartial('partial1.html')">Click to load partial 1</button>
<button ng-click="loadPartial('partial2.html')">Click to load partial 2</button>
<button ng-click="loadPartial('partial3.html')">Click to load partial 3</button>
<div views></div>
</body>
</html>
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', ['$scope', 'viewsAPI', function(scope, viewsAPI) {
scope.loadPartial = function (name) {
viewsAPI.addView(name);
};
}]);
app.factory('viewsAPI', function () {
return {
views: [],
action: null,
addView: function (viewName, options) {
var view = { name: viewName, options: options };
this.action = { type: 'add', view: view };
},
setView: function (viewName, options) {
var view = { name: viewName, options: options };
this.action = { type: 'set', view: view };
},
removeView: function () {
this.action = { type: 'remove' };
}
}
});
app.directive('views', ['$pile', function (pile) {
return {
restrict: 'A',
scope: {},
replace: true,
template: '<div class="views"></div>',
controller: ['$scope', 'viewsAPI', function (scope, viewsAPI) {
scope.api = viewsAPI;
scope.$watch('api.action', actionChange, true);
function actionChange (action) {
if (!action) return;
if (action.type == 'add') {
var view = scope.addView(action.view);
scope.api.views.push(view);
}
else if (action.type == 'set') {
scope.setView(action.view);
}
else if (action.type == 'remove') {
scope.removeView();
}
}
}],
link: function (scope, elm) {
scope.addView = function (view) {
var v = pile('<div class="view-wrapper" ng-include="\'' + view.name + '\'" ng-animate="fade"></div>')(scope);
elm.append(v);
return v;
};
scope.setView = function (view) {
};
scope.removeView = function () {
};
}
};
}]);
styles.css
.fade-enter-setup { -webkit-transition: all 3s linear; opacity: 0; }
.fade-enter-setup { opacity: 1; }
partial1.html
<div>Hello I am a partial 1</div>
partial2.html
<div>PARTIAL 2-------------------</div>
partial3.html
<div>
33333333333333333333333333
<br />
this is partial 3
<br />
33333333333333333333333333
</div>
I have the following AngularJS (v1.1.4) code and am trying to fade-in (animate) the ng-include when it is added to the DOM. What am I doing wrong? Also, if anyone can suggest a better way of passing add/set/remove mands to the directive rather than watching the 'action' property, that would be much appreciated.
Plunker is here: http://plnkr.co/edit/rcgpI0n8fGWj6o01Mp3b?p=preview
index.html
<!doctype html>
<html ng-app="plunker" >
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="styles.css" />
<script>document.write('<base href="' + document.location + '" />');</script>
<script src="http://code.angularjs/1.1.4/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<button ng-click="loadPartial('partial1.html')">Click to load partial 1</button>
<button ng-click="loadPartial('partial2.html')">Click to load partial 2</button>
<button ng-click="loadPartial('partial3.html')">Click to load partial 3</button>
<div views></div>
</body>
</html>
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', ['$scope', 'viewsAPI', function(scope, viewsAPI) {
scope.loadPartial = function (name) {
viewsAPI.addView(name);
};
}]);
app.factory('viewsAPI', function () {
return {
views: [],
action: null,
addView: function (viewName, options) {
var view = { name: viewName, options: options };
this.action = { type: 'add', view: view };
},
setView: function (viewName, options) {
var view = { name: viewName, options: options };
this.action = { type: 'set', view: view };
},
removeView: function () {
this.action = { type: 'remove' };
}
}
});
app.directive('views', ['$pile', function (pile) {
return {
restrict: 'A',
scope: {},
replace: true,
template: '<div class="views"></div>',
controller: ['$scope', 'viewsAPI', function (scope, viewsAPI) {
scope.api = viewsAPI;
scope.$watch('api.action', actionChange, true);
function actionChange (action) {
if (!action) return;
if (action.type == 'add') {
var view = scope.addView(action.view);
scope.api.views.push(view);
}
else if (action.type == 'set') {
scope.setView(action.view);
}
else if (action.type == 'remove') {
scope.removeView();
}
}
}],
link: function (scope, elm) {
scope.addView = function (view) {
var v = pile('<div class="view-wrapper" ng-include="\'' + view.name + '\'" ng-animate="fade"></div>')(scope);
elm.append(v);
return v;
};
scope.setView = function (view) {
};
scope.removeView = function () {
};
}
};
}]);
styles.css
.fade-enter-setup { -webkit-transition: all 3s linear; opacity: 0; }
.fade-enter-setup { opacity: 1; }
partial1.html
<div>Hello I am a partial 1</div>
partial2.html
<div>PARTIAL 2-------------------</div>
partial3.html
<div>
33333333333333333333333333
<br />
this is partial 3
<br />
33333333333333333333333333
</div>
Share
Improve this question
asked May 9, 2013 at 12:49
romiemromiem
9,0407 gold badges32 silver badges37 bronze badges
2 Answers
Reset to default 3If you are still interested, i accidently created a plunker today, that should answer your long ago question.
http://plnkr.co/Gd5f6J
Now with the latest 1.2 stable release, if angular finds ngAnimate module, it will add specific css classes to the dom, when a built-in directive like ng-if, ng-switch, ng-view detected, that a child has changed. Those classes trigger your css transitions, so if your view partial takes a long time to load, the animation will start, when it was fully loaded.
index.html:
<div class="view-animate-container">
<div class="well slide" ng-view>
<!-- view container. Asynchronously loaded view templates are placed here -->
</div>
</div>
app.js:
angular.module('myApp', ['ngRoute', 'ngAnimate'])
.run(function($rootScope, $location){
$rootScope.matchesRoute = function() {
for(var i=0; i<arguments.length; i++) {
if($location.path() === arguments[i]) {
return true;
}
}
return false;
}
})
.config(function($routeProvider) {
$routeProvider
.when('/bellsAndWhistles', {templateUrl: 'bellsAndWhistles.html', controller: angular.noop()})
.when('/about', {templateUrl: 'about.html', controller: angular.noop()})
.otherwise({redirectTo: '', templateUrl: 'home.html'});
});
styles.css:
html, body{
height: 100%;
}
.view-animate-container {
position: relative;
overflow: hidden;
height:100%;
}
.view-animate-container > .slide.ng-enter,
.view-animate-container > .slide.ng-leave {
-webkit-transition: all ease 0.5s;
-moz-transition: all ease 0.5s;
-o-transition: all ease 0.5s;
transition: all ease 0.5s;
width: 100%;
position:absolute;
}
.view-animate-container > .slide.ng-enter {
left:100%;
opacity: 0;
}
.view-animate-container > .slide.ng-enter.ng-enter-active {
left:0;
opacity: 1;
}
.view-animate-container > .slide.ng-leave.ng-leave-active {
left: -100%;
opacity: 0;
}
I came across this same issue. However, the behavior of content below the animated view will be jumpy and undesired. See this Plunker Example.
So, to expand on @angabriel 's answer, I worked on an alternative. See the following Plunker Example, which is a modification of @angabriel's work. You will need to use Chrome to see it working, since I did not had the chance to add the css for other browsers.
The main difference is the CSS. It is worth mentioning that I had to override the following:
min-height
margin-top
margin-bottom
padding-top
padding-bottom
To make the transition smooth, since bootstrap adds some rules that make the transition jumpy once the element that leaving is removed from the DOM.
/* CSS */
.view-animate-container > .slide.ng-enter,
.view-animate-container > .slide.ng-leave {
-webkit-transition: all ease 0.5s;
-moz-transition: all ease 0.5s;
-o-transition: all ease 0.5s;
transition: all ease 0.5s;
width: 100%;
position: relative;
}
.view-animate-container > .slide.ng-enter {
-webkit-animation-name: slideIn;
animation-name: slideIn;
-webkit-animation-duration: .5s;
animation-duration: .5s;
-webkit-animation: slideIn .5s;
animation: slideIn .5s;
}
.view-animate-container > .slide.ng-leave {
-webkit-animation-name: slideOut;
animation-name: slideOut;
-webkit-animation-duration: .5s;
animation-duration: .5s;
-webkit-animation: slideOut .5s;
animation: slideOut .5s;
}
@keyframes slideOut {
from {
opacity: 1;
max-height: 500px;
}
50% {
opacity: 0;
max-height: 0px;
margin-top: 0;
min-height: 0;
margin-bottom: 0;
padding-bottom: 0;
padding-top: 0;
}
to {
opacity: 0;
max-height: 0px;
margin-top: 0;
min-height: 0;
margin-bottom: 0;
padding-bottom: 0;
padding-top: 0;
}
}
@keyframes slideIn {
from {
opacity: 0;
max-height: 0px;
margin-top: 0;
min-height: 0;
margin-bottom: 0;
padding-bottom: 0;
padding-top: 0;
}
50% {
max-height: 0;
opacity: 0;
margin-top: 0;
min-height: 0;
margin-bottom: 0;
padding-bottom: 0;
padding-top: 0;
}
to {
max-height: 500px;
opacity: 1;
}
}
PROS
Content below the view div will not be jumpy
CONS
Content height: If the view content is grater than 500px
(in my case) it will animate to 500px then jump to its full height (as pointed out by Isaac)
Thanks
本文标签: javascriptAngularJShow to animate nginclude that is dynamically compiled and addedStack Overflow
版权声明:本文标题:javascript - AngularJS - how to animate ng-include that is dynamically compiled and added - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745150359a2644893.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论