AngularJS trigger slide-toggle in Controller - angularjs

I am using for my Slide up/down effect this genius written .js modul.
https://github.com/EricWVGG/AngularSlideables
http://jsfiddle.net/3sVz8/19/
I could include it to my project and it is working the way I want.
But now I want to trigger this inside my controller, how do I do this?
html
Open smoothly
<div id="derp" class="slideable">
open/hidden content
</div>
.js
var myApp = angular.module('myApp', ['ngAnimate', 'angularSlideables']);
angular.module('angularSlideables', [])
.directive('slideable', function () {
return {
all the code from the github
})
myApp.controller("ContactControllerHeading", function ($scope, $http) {
$scope.Triggerhere= function() {
/* trigger here this slide-toggle="#derp" */
}
});
Thank you a lot

I gave up solving it with this. I used jquery slide up and down function which seems to be a adequate solution
http://www.w3schools.com/jquery/eff_slidetoggle.asp

Related

AngularJS - $templateCache is not defined

I am trying to load a template file in an AngularStrap popover, however I am having trouble using $templateCache. I seem to be a step further back than the other SO questions, hence this seemingly double one.
Following the API docs I added a <script type="text/ng-template" id="popoverTemplate.html"></script> right before the closing </body> tag. When I use <div ng-include="'popoverTemplate.html'"></div> on my page, I get nothing. If I try using console.log($templateCache.get("popoverTemplate.html")) I get "$templateCache is not defined", which leads me to assume I am missing a crucial step. However, I can't find how to do it in the docs or other SO questions.
EDIT:
Injecting the service was the missing link. However, when I inject the service, the controller's other function no longer works, but if you inject al the function's parameters the working code becomes:
(function() {
"use strict";
angular.module("app").controller("managerController", ["$scope", "imageHierarchyRepository", "$templateCache", function ($scope, imageHierarchyRepository, $templateCache) {
imageHierarchyRepository.query(function(data) {
$scope.hierarchies = data;
});
var template = $templateCache.get("popoverTemplate.html");
console.log(template);
}]);
})();
To use the template script tag . You have to insert it inside the angular application. That is inside the element with the ng-app attribute or the element used to bootstrap the app if you don't use the ng-app tag.
<body ng-app="myapp">
<div ng-template="'myTemplate.html'"></div>
<script type="text/ng-template" id="myTemplate.html">
// whate ever
</script>
</body>
If you want to retrieve the template on a component of the application then you need to inject the service where you want to consume it:
controller('FooCtrl', ['$templateCache', function ($templateCache) {
var template = $templateCache.get('myTemplate.html');
}]);
Or
controller('FooCtlr', FooCtrl);
FooCtrl ($templateCache) {};
FooCtrl.$inject = ['$templateCache'];
EDIT
Do not register two controllers with the same name because then you override the first one with the last one.
(function() {
"use strict";
angular.module("app").controller("managerController",["$scope", "imageHierarchyRepository", "$templateCache", function ($scope, imageHierarchyRepository, $templateCache) {
var template = $templateCache.get("popoverTemplate.html");
console.log(template);
imageHierarchyRepository.query(function(data) {
$scope.hierarchies = data;
});
}]);
})();
Small addition: Although there are few ways to achieve your goals, like wrapping your whole HTML in <script> tags and all that, the best approach for me was to add the $templateCache logic into each Angular directive. This way, I could avoid using any external packages like grunt angular-templates (which is excellent but overkill for my app).
angular.module('MyApp')
.directive('MyDirective', ['$templateCache', function($templateCache) {
return {
restrict: 'E',
template: $templateCache.get('MyTemplate').data,
controller: 'MyController',
controllerAs: 'MyController'
};
}]).run(function($templateCache, $http) {
$http.get('templates/MyTemplate.html').then(function(response) {
$templateCache.put('MyTemplate', response);
})
});
Hope this helps!

Adding a new javascript library makes my HTML invisible

When I add the "underscore.string" library in my controller everything in the page disappears. I used this thread on stackoverflow to inject underscore to my controller.
This is my controller:
var underscore = angular.module('underscore', []);
underscore.factory('_', ['$window', function($window) {
return $window._; // assumes underscore has already been loaded on the page
}]);
angular.module('weatherApp', ['underscore'])
.controller('MainCtrl', ['$scope', '$log', 'weatherService','_', function ($scope, $log, weatherService, _) { //controller code}
I have a main index.html and a main.html. main html is inside of a div in index.html.
What might be the problem? There are no errors on the console.
There's nothing wrong with the code you've provided, it's probably in your HTML, which you must make sure has all the tags closed.
Here's a sample on plunkr
http://embed.plnkr.co/O34NTqMs33IGYbGJXM5U

AngularJS - Running a function once on load

I am trying to run an $http function when my AngularJS application first loads.
This $http function needs to finish before any of the controllers in my application could properly function. How would I go about doing this? This sounds like a promise, but it sounds like I would be creating a promise in each controller...
I currently have the function that I want to run first like this:
app.run(function() {
$http.get('link').success(function(data) {
// success function. The data that I get from this HTTP call will be saved to a service.
}).error(function(error) {
});
});
However, sometimes the controller will load before the http call finishes.
The problem
Angular is not dynamic, you cannot add controller dynamically neither factory, etc. Also you cannot defer controller bootstrap, angular loads everything together, and it's quite disadvantage (will be fixed in Angular 2)
The cure
But javascript itself has very important feature - closure, which works anywhere, anytime.
And angular has some internal services that can be injected outside of angular ecosystem, even into browser console. Those services injected as shown below. We technically could use anything else (jQuery.ajax, window.fetch, or even with XMLHttpRequest), but let's stick with total angular solution
var $http_injected = angular.injector(["ng"]).get("$http");
The act
First of all, we defer whole angular app bootstrap, inject http service. Then you make your needed request, receive data and then closure get's to work, we pass received data into some service, or we could also assign in to some angular.constant or angular.value but let's just make demo with angular.service, so when your service has data, bootstrap whole app, so that all controllers get initialized with your needed data
Basically that kind of tasks solved like this
<body>
<div ng-controller="Controller1">
<b>Controller1</b>
{{text}}
{{setting.data.name}}
</div>
<hr>
<div ng-controller="Controller2">
<b>Controller2</b>
{{text}}
{{setting.data.name}}
</div>
<script>
//define preloader
var $http_injected = angular.injector(["ng"]).get("$http");
$http_injected.get('http://jsonplaceholder.typicode.com/users/1').then(function(successResponse) {
//define app
angular.module('app', []);
//define test controllers
//note, usually we see 'controller1 loaded' text before 'settings applied', because controller initialized with this data, but in this demo, we will not see 'controller1 loaded' text, as we use closure to assign data, so it's instantly changed
angular.module('app').controller('Controller1', function($scope, AppSetting) {
$scope.text = 'controller1 loaded';
$scope.setting = AppSetting.setting;
$scope.$watch('setting', function(e1 ,e2){
$scope.text = 'settings applied'
});
});
angular.module('app').controller('Controller2', function($scope, AppSetting) {
$scope.text = 'controller2 loaded';
$scope.setting = AppSetting.setting;
$scope.$watch('setting', function(e1 ,e2){
$scope.text = 'settings applied'
});
});
//define test services, note we assign it here, it's possible
//because of javascript awesomeness (closure)
angular.module('app').service('AppSetting', function() {
this.setting = successResponse;
});
//bootstrap app, we cannot use ng-app, as it loads app instantly
//but we bootstrap it manually when you settings come
angular.bootstrap(document.body, ['app']);
});
</script>
</body>
Plunker demo
You can do this when you configure your routes
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
controller: 'MainCtrl',
templateUrl: 'main.html',
resolve: {
data: ['$http',
function($http)
{
return $http.get('/api/data').then(
function success(response) { return response.data.rows[0]; },
function error(reason) { return false; }
);
}
]
}
});
}]);
Similar question:
AngularJS - routeProvider resolve calling a service method
AngularJS: $routeProvider when resolve $http returns response obj instead of my obj
Heres a plunkr I found using a service, which is what I would recommend.
http://plnkr.co/edit/XKGC1h?p=info

Access Angular $scope in plain javascript

I have a Controller which has something like this...
angular.module('kZoneApp').controller('DemandController', ['$http', '$scope', '$rootScope', 'dataFactory', '$window', '$routeParams','$sce', function ($http, $scope,$rootScope, dataFactory, $window, $routeParams,$sce) {
$scope.channel = $routeParams.channel;
now within my page.html, I want to do the following....
<script>
YoutubeVideoPlayer.openVideo('{{channel}}');
</script>
please note, I am using Routes, and page.html is loaded into my ng-view Via a Route.
<div id="myView" class="reveal-animation" ng-view></div>
I tried below code, but it returns undefined....
$().ready(function () {
var channel = angular.element("#myView").scope().channel
YoutubeVideoPlayer.openVideo(channel);
})
How can I get the value of Channel within my Template View?
Update
below works...but I am sure there has to be a cleaner solution
setTimeout(function () {
alert(angular.element("#myView").scope().channel)
}, 500);
A workaround solution should be creating a variable before your Angular.module definition.
var scopeInAngular = null;
and inside controller assign controller to your variable.
scopeInAngular = $scope;
then if you manipulate anything inside angular view use
scopeInAngular.$apply();

how to manage big angular app

I'm having trouble managing my app. I would like to separate my controllers on several files. I read Brian's Ford blog ( http://briantford.com/blog/huuuuuge-angular-apps.html ) but I cannot quite understand how should I do it.
On my controller.js file I had something like this :
function loginCtrl($scope){
....
}
function landingCtrl($scope){
...
}
And the only way I found to separate controller per file is to do this:
app.js:
var musicApp = angular.module('musicApp', []);
controller1.js:
musicApp.controller('loginController', ['$scope', loginCtrl],function loginCtrl($scope){
....
});
controller2.js:
musicApp.controller('landingCtrl', ['$scope', landingCtrl],function landingCtrl($scope){
....
});
Is there a better way to do this?
I'm using a similar way as below:
Main.js
angular.module('app', []);
FooCtrl.js
angular.module("app").controller("FooCtrl", [
"$scope", function($scope) {
}
]);
Another way adopted by google is:
# init empty Object
var docsApp = {
controller: {},
directive: {},
serviceFactory: {}
};
# FooCtrl.js
docsApp.controller.FooCtrl = ['$scope', function($scope){}]
# BarCtrl.js
docsApp.controller.BarCtrl = ['$scope', function($scope){}]
... add services
... directives
# bootstrap angular
angular.module('docsApp', ['...']).
config(...).
factory(docsApp.serviceFactory).
directive(docsApp.directive).
controller(docsApp.controller);
Take a look at this js from google angularjs tutorial: http://docs.angularjs.org/js/docs.js
You can achieve this in multiple ways.
one file for all your controllers using "."
musicApp.controller('loginController', ['$scope', loginCtrl,function loginCtrl($scope){
....
}]).controller('landingCtrl', ['$scope', landingCtrl,function landingCtrl($scope){
....
}]);
just remember to include the function inside the injected paramenters array.
or one controller for each file.
just need to include every js file with whatever method you are using (script tag, requirejs, etc.)
I have something similar:
main_router.js:
var myApp = angular.module('theApp', ['controllers'])...
var controllers = angular.module('controllers', []);
some_controller.js:
controllers.controller('SomeCtrl', ['$scope',
function ($scope) { ... }
]);

Resources