ngAnimate breaks existing ui.bootstrap.carousel - javascript

I have this current app.js
angular.module('app', ['ngRoute', 'ngSanitize', 'ui.bootstrap','ui.router', 'com.2fdevs.videogular', 'com.2fdevs.videogular.plugins.controls', 'com.2fdevs.videogular.plugins.overlayplay',
'com.2fdevs.videogular.plugins.poster', 'com.2fdevs.videogular.plugins.buffering', 'ngDraggable','angular-loading-bar', 'chart.js', 'angularSpinner'])
and I include the needed javascript files in my index.html
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-resource.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-route.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-sanitize.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.1/ui-bootstrap-tpls.min.js"></script>
With this, the carousel is working at least, there is no transition animation, but if I click on the arrow it switches to the next one.
then I added the angular-animate to the index.html:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-animate.js"></script>
and ngAnimate to the app.js as dependency.
But this break the carousel. With this, the carousel won't go forward on its own and a click on the arrow will do nothing. I do not see any errors in the console and not at all why this is not working. Am I missing some css stuff or what?

May be a little late here, but there is a solution to this. Make a directive which essentially disables ng-animate:
app.directive('disableAnimation', function ($animate) {
return {
restrict: 'A',
link: function ($scope, $element, $attrs) {
$attrs.$observe('disableAnimation', function (value) {
$animate.enabled(!value, $element);
});
}
}
});
Then add attribute "disable-animation='true'" to your carousel tag. This solution was suggested by another user on a different question. I'm trying desperately to find him and give him the credit he deserves, I'll make an edit if I locate it.

Related

Angular: A controller with this name is not registered

I've been trying to figure this out for a few hours now, and I can't seem to find the problem. I've read some other questions with similar problems, but they don't have any solutions that have worked for me.
I am having trouble registering my controllers. I am not able to register controllers outside of the file in which I declare the app. Originally, I set up the 'MainController' in a separate file, which failed. I was getting an error saying that "The controller with the name 'MainController' is not registered". Once I put MainController in the same file as the app is declared, there were no problems. However, when I have a lot of code, I don't want all the controllers in the same file, as it will become too difficult to read. Here are examples of my code:
angular.module('myApp', ['ngRoute']);
angular.module('myApp')
.controller('MainController', MainController);
I am keeping other controllers in different files, and they are not registering. For example, in home.controller.js:
angular.module('myApp')
.controller('HomeController', HomeController);
function HomeController(HomeService) {
}
This controller will not register, and I don't know why. Each HTML partial in ng-view has its own controller, and the ng-view is within the MainController. Here is the app.config.js file:
angular.module('myApp')
.config(function($routeProvider, $locationProvider) {
$routeProvider.when('/home', {
templateUrl: 'views/home.html',
controller: 'HomeController as home'
}).when('/profile', {
templateUrl: 'views/profile.html',
controller: 'ProfileController as profile'
});
$locationProvider.html5Mode(true);
});
Here is index.html:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title>My App</title>
<script src="vendors/angular.min.js"></script>
<script src="vendors/angular-route.min.js"></script>
<script src="scripts/app.module.js"></script>
<script src="scripts/app.config.js"></script>
<scripts src="scripts/home.controller.js"></scripts>
<scripts src="scripts/profile.controller.js"></scripts>
<script src="scripts/main.service.js"></script>
<script src="scripts/home.service.js"></script>
<script src="scripts/profile.service.js"></script>
<base href="/" />
</head>
<body ng-controller="MainController as main">
<header>
<h1>My App</h1>
</header>
<!-- Content varies -->
<div class="container">
<ng-view></ng-view>
</div>
</body>
</html>
I have successfully built projects like this in the past without problem, but I can't find any issue compared to those projects. Any help is appreciated!
When I've had this issue in the past, it was related to script loading order, especially with using async script loading. You don't appear to be doing that.
To troubleshoot:
Fire a console log statement inside the controller's function body (console.log('registering controller x')). This statement will either not show up, or will show up after the error.
Angular used to (and I presume it still does) try to wait for app to load and all controllers to register to app before running the code. Either Angular isn't waiting on this controller, or this controller isn't running.
From there, you would verify that the reference to the file is correct (put a console.log at the top of the file), or determine how Angular decides when it believes all controllers are loaded and why it doesn't wait on your controller.
I haven't dealt with Angular since 1.2, because I think it's a pretty bad framework. But that was my experience then, and it seems like the same basic architecture for this. Back then it was relying on Document.ready. I really hope they don't do that anymore (that's where I ran into my async script loader problems).
Best of luck.

Using jQuery plugin in AngularJs App

I want to use this tinyColorPicker plugin https://github.com/PitPik/tinyColorPicker but it's proving extremely difficult to use it in my angular app.
I keep getting this error:
TypeError: element.colorPicker is not a function
In my index.html
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/tinycolorpicker/lib/jquery.tinycolorpicker.js"></script>
I have then made a directive to instantiate the plugin
'use strict';
angular.module('myApp')
.directive('colorWheel', function() {
return {
restrict: 'A',
link: function(scope, element) {
element.colorPicker();
}
};
});
And in my HTML I have this div with the directive
<div id="colorWheel" color-wheel></div>
According to their docs that is all I have to do. I must be missing something key when it comes to integrating it with Angular. Can anyone see anything? Thanks
Element is not a jQuery object, it is an angular object. The plugin is is exposed on the jQuery object. Try using jQuery selectors in your link fn e.g. jQuery("#yourDomId").colorPicker()
You have to load jQuery before you loading angularjs.
If you will load jquery after loading angular you will get the jqLite.
<script src="jquery.js"></script>
<sciprt src="angular.js"></script>

How to use <md-progress-linear> in AngularJS MD?

I am using Material Design in my AngularJS app and I want to add a progress bar while my page is loading.
MD uses md-progress-* Directive to get a loading bar:
<md-progress-linear md-mode="determinate" value="..."></md-progress-linear>
In my app I tried to get loading progress complete on $viewContentLoaded:
HTML:
<html ng-app="app">
<body ng-controller="AppCtrl">
<md-progress-circular ng-if="determinateValue === 100" md-mode="determinate" value="{{determinateValue}}"></md-progress-circular>
...
</body>
</html>
JS:
'use strict';
angular.module('app', ['ngMaterial', 'ngAnimate'])
.controller('AppCtrl', function ($scope) {
$scope.determinateValue = 0;
$scope.$on('$viewContentLoaded', function(){
$scope.determinateValue = 100;
});
});
But it doesn't work and I do not get any error.
ps. the <md-progress-linear> tag is disappeared from the DOM.
Firstly, use md-mode="indeterminate" as your loading is binary and has only two states. get rid of the ng-if and use the value attribute bound to $scope.determinateValue. So:
<md-progress-circular md-mode="indeterminate" value="determinateValue"></md-progress-circular>
I'd rename the determinateValue to something more precise and reflective also. Also the tag disappears cause the determinateValue is always at some point being assigned to 100 ie your content is loading

I am trying to understand AngularJS's controllerAs syntax

However after writing up a few examples to play around with the controllers would not load. I was getting an error:
firstController is not a function
After some googling I found that Angular 1.3.x no longer supports global controllers. All the examples I have seen of the new way of creating controllers seem to create them in my app.js file. I am confused, does this now mean that I must create all my controllers here rather than having a dedicated file for each controller. I have tried this to create the controller and still no luck:
UPDATE: I changed my controller to match jedanput's answer but changed $scope to this.
app.controller('firstController', [function(){
this.name = "Tim";
}]);
Also I find it very annoying that all that the majority of the example out there still reference the way it was done in Angular 1.2.
Any help would be greatly appreciated as I am having trouble understanding this issue.
EDIT: Here is my index.html file. Hopefully this will help you guys understand what is going wrong.
<!DOCTYPE html>
<html lang="en" xmlns:ng="http://angularjs.org" id="ng-app" ng-app="myApp">
<head >
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>ControllerAs</title>
<meta name="description" content="">
</head>
<body>
<div class="content" ng-view=""></div>
<!-- jQuery -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- AngularJS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.6/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.6/angular-route.js"></script>
<script type="text/javascript" src="../js/app.js"></script>
<!--Directives-->
<script type="text/javascript" src="../js/directives/it-works.js"> </script>
<!--Controllers-->
<script type="text/javascript" src="../js/controllers/firstController.js"></script>
<script type="text/javascript" src="../js/controllers/secondController.js"></script>
</body>
</html>
So far I have avoided Controllers as everything I have been doing could be done with directives and services but it is time I understood more about controllers. I think it may be something fundamental I am missing. Again any help is greatly appreciated.
UPDATE: still getting the same error. This is my app.js file. Maybe it can shed some light on the problem.
var app = angular.module('myApp',[
'ngRoute'
]);
app.config(function($routeProvider) {
$routeProvider.when('/', {
templateUrl: "../partials/test-skeleton.html"
})
});
It should be
app.controller('firstController', ['$scope', function($scope){
$scope.name = "Tim";
}]);
Also, controllerAs syntax is synthetic sugar for the scope simply, you avoid using this:
<div ng-controller="oneCtrl">
{{name}}
</div>
And instead use this:
<div ng-controller="oneCtrl as one">
{{one.name}}
</div>
Which helps tremendously when you have nested controllers.
You're right, Angular allows for multiple different notations and that can be annoying and confusing. I would recommend you to stick with the guidelines from John Papas Angular Style Guide. He uses this:
(function() {
'use strict';
// Get reference to your application
angular.module('myapp')
// Add the controller
.controller('mycontroller',controller);
// This makes the injection of the controller arguments
// explicit
controller.$inject = ['$scope', '$http'];
// Here the actual controller is defined - where
// the arguments are injected on the same location as
// in the previous array
function controller($scope, $http) {
// Controller logic
});
})();
You want to keep stuff out of the global space. Really - you do. That's why he wraps everything in an Immediately-Invoked Function Expression (IIFE).
Also - you want to explicitly define what you're injecting ( the $inject array ). If not, you will not be able to minify later.
So I'm sorry - I just added another way of defining your AngularJS artefacts. From what I understand, this is one the more well known style guides out there. I've heard that he's working closely with the Angular guys to make sure his style guide will also make it easier to transition to the new Angular version.
And no - you do not need to put everything in 1 file - just make sure you have a file with angular.module('myapp',[]) loaded before any of the other files. This will declare the myapp module and will append the controller to it.
As I'm writing this - I realize that there's also another way: you create a new module in this file, append the controller and then load that module into your application. But yeah ... it's confusing.

AngularJS : dynamic stylesheet link tag fires request too soon

I'm facing an issue similar (but not identical, please bear with me) to the one described in Conditionally-rendering css in html head
I'm also "lazily" loading a stylesheet, getting the filename from a scope variable that I initialize at the very beginning of my controllers :
<link rel="stylesheet" data-ng-href="css/{{ filename }}.css" />
As I'm using ng-href (here in its data- form), I'm indeed avoiding unwanted requests such as :
http://localhost/css/%7B%7B%20filename%7D%7D.css
But it all still fires too soon, and I'm getting this almost every time :
http://localhost/css/.css
Which seems to mean the request fires between the moment when Angular removes its own markup and the moment it replaces it with the correct value (which it does, a moment later, and then my stylesheet loads properly). I reckon it's not even possible...!?
I figured I might be providing a value for the filename scope variable too late, but as I said, it's the first thing done in my controller :
angular.module('myControllers', [])
.controller('TestCtrl', ['$scope', function($scope) {
$scope.filename = 'test';
// some more code...
}]);
I'm using Angular 1.1.5 ; is there anything I can do about it ? It's not that big of a deal, but it would still be better if I could fix it.
EDIT : Here comes the complete code, as requested. I won't include page templates as they are irrelevant regarding the issue.
index.html :
<!DOCTYPE html>
<html lang="en" data-ng-app="myapp">
<head>
<meta charset="utf-8" />
<title>My App</title>
<link rel="stylesheet" data-ng-href="/assets/css/{{ filename }}.css" />
</head>
<body>
<div id="app" class="app" style="display: none;" data-ng-view></div>
<script src="/assets/js/lib/angular/angular.min.js"></script>
<script src="/assets/js/app/app.js"></script>
<script src="/assets/js/app/controllers.js"></script>
</body>
</html>
app.js :
var app = angular.module('myapp', ['myControllers'])
.config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) {
$locationProvider.hashPrefix('!');
$routeProvider
.when('/', {
templateUrl: 'path/to/my/template.html',
controller: 'TestCtrl'
})
.otherwise({ redirectTo: '/' });
}]);
app.run();
controllers.js :
angular.module('myControllers', [])
.controller('TestCtrl', ['$scope', '$rootScope', function($scope, $rootScope) {
$rootScope.filename = 'stylesheet';
}]);
(Yes, I tried with an empty controller just like this one, same issue.)
I solved it by adding an ngIf directive to the link tag, so it's not rendered until filename isn't falsy. Kinda dirty I know, but it actually works !
<link rel="stylesheet" data-ng-if="filename" data-ng-href="css/{{ filename }}.css" />
Works for me in a small example.
That the algo:
attr.$observe(normalized, function(value) {
if (!value)
return;
attr.$set(attrName, value);
// on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
// then calling element.setAttribute('src', 'foo') doesn't do anything, so we need
// to set the property as well to achieve the desired effect.
// we use attr[attrName] value since $set can sanitize the url.
if (msie) element.prop(attrName, attr[attrName]);
});
The function immediately returns if that value is false e.g. undefined.
Could you post the complete code,
the should be another problem.
Edit:
Binding a Controller via the Route-Provider only binds this controller to your element with the ng-view element.
You could do something like this:
HTML:
<head ng-controller="HeadCtrl">
<link rel="stylesheet" data-ng-href="{{ filename }}.css">
</head>
JS:
app.controller("HeadCtrl",function ($scope)
{
$scope.filename = 'apartment';
});
Btw
ng-cloak not 'fires' to hide something.
You have to add a CSS class for it.
http://docs.angularjs.org/api/ng.directive:ngCloak
[ng\:cloak],
[ng-cloak],
[data-ng-cloak],
[x-ng-cloak],
.ng-cloak,
.x-ng-cloak {
display: none !important;
}
Don't to inline css please :)
Its a simple directive that removes the ng-cloak attribute when angular finished loading and starts interpreting the directives.
Then your code switched to visible via normal browser-render mechanisms.

Categories