Calling an AngularJS controller function from outside of it - javascript

I have the following code:
app.controller('MatrixExpertCtrl', function($scope,$http){
$scope.PassedMatrix=[];
$scope.GetMatrixFromServer=function(){
$http.get("http://localhost:3000/getmatrixfromdb").success(function(resp){
alert("The matrix grabbed from the server is: " + resp[0].ans);
$scope.PassedMatrix.push(resp[0].ans);
});
};
$scope.DispSize=function(){
alert("testing");
alert("The size is "+$scope.PassedMatrix[0].size) ;
};
//$scope.GetMatrixFromServer();
});
Now, suppose, in HTML, I have something like this:
<div class="col-sm-3 col-md-3 col-lg-3">
<div class="text-center">
<h3>Example Survey</h3>
<p>example paragrah</p>
<p>More random text</p>
<p>ending the paragraphs</p>
<button id="updmat" ng-click="DispSize();" type="button" class="btn btn-default">Updates</button>
</div>
//Much more code
<div id="body2">
<div class="col-sm-6 col-md-6 col-lg-6" style="background-color:#ecf0f1;">
<div ng-controller="MatrixExpertCtrl" ng-app="app" data-ng-init="GetMatrixFromServer()">
<div class="text-center">
Meaning with this:
Is it possible to call a function that is defined inside a controller, from outside of the scope of that same controller?
I need this because the function is manipulating a shared object, owned by the controller in a very very simple fashion (for example, clicking on the button changes the color of a given element).
I am having trouble to make this work, any help will be appreciated.
I think that declaring some data structures as global would help me solving this problem, but, I would like to avoid doing that because, besides it being bad practice, it might bring me more problems in the future.

If i understand your problem correctly than what you basically do have is one utility function which will work on your shared object and do your useful things (i.e. clicking on the button changes the color of a given element) and now you do require the same behaviour in another controller outside of it's scope. You can achieve the same thing in 2 different ways :
1).Create a service and make it available in your controllers like this :
<!doctype html>
<html ng-app="myApp">
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.angularjs.org/1.1.2/angular.min.js"></script>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.factory('myService', function() {
return {
changeColour: function() {
alert("Changing the colour to green!");
}
};
});
myApp.controller('MainCtrl', ['$scope', 'myService', function($scope,
myService) {
$scope.callChangeColour = function() {
myService.changeColour();
}
}]);
</script>
</head>
<body ng-controller="MainCtrl">
<button ng-click="callChangeColour()">Call ChangeColour</button>
</body>
</html>
Pros&Cons: More angularistic way, but overhead to add dependency in every different controllers and adding methods accordingly.
2).Access it via rootscope
<!doctype html>
<html ng-app="myApp">
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.angularjs.org/1.1.2/angular.min.js"></script>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.run(function($rootScope) {
$rootScope.globalChangeColour = function() {
alert("Changing the colour to green!");
};
});
myApp.controller('MainCtrl', ['$scope', function($scope){
}]);
</script>
</head>
<body ng-controller="MainCtrl">
<button ng-click="globalChangeColour()">Call global changing colour</button>
</body>
</html>
Pros&Cons: In this way, all of your templates can call your method without having to pass it to the template from the controller. polluting Root scope if there are lots of such methods.

try removing semicolon
ng-click="DispSize()"
because it binds ng-click directive to the function.

Related

How can I use javascript code inside angularjs?

I need to run this code in angularjs.
When I try to execute this model function it is not running.
It is not even showing alert or console.
So what is the way to use this script files in angularjs
Here is my code in example.html:
<div>
{{sample}}
</div>
<div><button ng-click="name()"></div>
<script>
function name(){
alert("text");
}
</script>
If i understand your requirement correctly,
You need to execute a separate java-script function.
For an angular application it is not a proper way to run javascript out of scope of angular.
any if it is absolutely requried you can try replacing ng-click="name()" with onclick="name()"
var app = angular.module("app", []);
app.controller('exampleController', [function() {
this.myFunction = function() {
alert("Iam from angular controller");
}
}]);
function myFunction() {
alert("Iam from javascript");
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="app" ng-controller="exampleController as ctrl">
<button ng-click="ctrl.myFunction()">click me</button>
<button onclick="myFunction()">click me</button>
</div>
#Update
If you want to use a java script library or function or constants in angularjs the my suggested way is to add a factory or service that ensure the library or function or constants but it is not simple as above solution.Here iam adding a snippet based on above solution
There are some advantages of using following approch :-
It will add dependency injection proprely which is a basic concept behind angularjs
It will ensure that the external function exist before starting app.
It will add more flexibility and control over the java script function in angular.
The below snippet will remove the external access of function and secure your application
This is the best way in which you can add external libraries like jquery loadash or any js libraries to your code
(function() {
function exampleController(myFunction) {
this.myFunction = function() {
alert("Iam from angular controller");
}
this.externalJSFunction = myFunction
};
exampleController.$inject = ['myFunction'];
function myFunctionFactory($window) {
if (!$window.myFunction) {
throw new Error("myFunction is not defined");
}
this.myFunction = $window.myFunction;
/* You can add
$window.myFunction = undefined;
if the function ($window.myFunction) is not required by
some other library or function in window scope
in such cases it gives added security by
restricting access of this from window scope and dis allows modification
*/
return this.myFunction;
}
myFunctionFactory.$inject = ['$window'];
var app = angular.module("app", []);
app.controller('exampleController', exampleController);
app.factory('myFunction', myFunctionFactory);
})();
function myFunction() {
alert("Iam from javascript");
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="app" ng-controller="exampleController as ctrl">
<button ng-click="ctrl.myFunction()">click me For angular Function</button>
<br/>
<button ng-click="ctrl.externalJSFunction()">click me For external JS Function </button>
<br/>
<button onclick="myFunction()">click me for checking exteranl acess </button>
</div>
your code should be like this....
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
<script >
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name=function(){
alert("text");
}
});
</script>
</head>
<body ng-controller="MainCtrl">
<div>
{{sample}}
</div>
<div><button ng-click="name()">click me</div>
</body>
</html>
You need to give angular js cdn first and then a create a module and controller like above
Here is a sample controller.
<body ng-app="myApp" ng-controller="myCtrl">
<div>
<button ng-click="name()">
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.name = name;
function name(){
alert("text");
}
});
</script>
</body>
You could use a directive, here is an example:
// in your JS source
angular.directive('something', [function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('click', function() {
alert('yup');
});
}
};
}]);
// in your HTML file
<button type="button" something>Click Me!</button>
This allows you to reuse your various code chunks / functions across your entire project pretty easily.
Another Solution
<!DOCTYPE html>
<html>
<head>
<title>example</title>
<script data-require="jquery#*" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
</head>
<body ng-app="app" ng-controller="exampleController as ctrl">
<button ng-click="ctrl.name()">click me to angular</button>
<button ng-click="name()" class="btn">click me to javascript</button>
<script>
var app = angular.module("app", []);
app.controller('exampleController', [function() {
this.name = function() {
alert("angular text");
}
}]);
//JQuery Lib must be included your project
$(document).on('click', '.btn', function() {
eval($(this).attr('ng-click'));
});
function name() {
alert("javascript text");
}
</script>
</body>
</html>
You should be able to run any javascript inside of an angular controller inside of a script tag in an html file.
Your html file should look something more like this:
<!DOCTYPE html>
<html>
<head>
<title>example</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
</head>
<body ng-app="app" ng-controller="exampleController as ctrl">
<button ng-click="ctrl.name()">click me</button>
</body>
</html>
<script>
var app = angular.module("app", []);
app.controller('exampleController', [function() {
this.name = function(){
alert("text");
}
}]);
</script>
Create a service layer and glue it inside the controller. Now, you can reuse the created function in multiple controllers.
For implementation,
How can I call javascript function in AngularJS controller?
I hope this helps!

AngularJs custom directive not getting invoked

I am new to AngularJs. I am trying to invoke custom directive but it is not getting invoked.
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="customDirective.js"></script>
</head>
<body>
<div ng-app="app">
<div ng-controller="MyController as ctrl">
<testingDirective></testingDirective>
{{ctrl.test}}
</div>
</div>
</body>
My javascript file looks like:
var app=angular.module('app',[]);
app.controller('MyController',[function(){
var self=this;
self.test='no';
}]);
app.directive('testingDirective',function(){
return{
restrict:'AE',
replace:true,
template:'<h1>Hello World Test</h1>'
};
});
Camel cased directive names have to be called using a hyphen. For example, if you have a directive named myDirective, you would use it in the markup as <my-directive></my-directive>.
Directive:
app.directive('testingDirective',function(){});
HTML Usage:
<testing-directive></testing-directive>

binding not working in nested controller

I'm new to Angular JS.
I have a few questions. Scope seems to be working with my first controller testController but not with my second controller controlspicy.
Why is not letting me print out $scope.greeting ? Shouldn't the binding work because I assigned a controller.
Here's a plunkr link which directs straight to the code.
http://plnkr.co/edit/NbED8vXNiZCqBjobrISa?p=preview
<!DOCTYPE html>
<html ng-app="newtest">
<head>
<script data-require="angular.js#*" data-semver="1.3.5" src="https://code.angularjs.org/1.3.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script src="spicy.js"></script>
</head>
<body ng-controller="testController">
<h1>Hello Plunker! {{message}}</h1>
<input type="text" name="firstName" ng-model="thetext">
{{double(thetext)}}
<h1 ng-controller="controlspicy">new test</h1>
<h2>{{greeting}}</h2>
</body>
</html>
script.js
var app = angular.module("newtest", [])
.controller("testController", ["$scope", function($scope) {
$scope.message = "hola";
$scope.double = function(value){
if (value == null){
return 0;
}
return value*2;
};
}]);
spicy.js
var appl = angular.module("thespicy", [])
.controller("controlspicy", ["$scope", function($scope){
$scope.greeting = "hello";
}]);
As previously mentioned by Preston you need to wrap the <h2> inside a tag with ng-controller. There is one more issue however.
controlspicy is defined in another module than the one you specify in ng-app.
Change angular.module("thespicy", []) in spicy.js to angular.module("newtest").
You should almost never use more than one module in one app. You could however divide it into different sub-modules but if your new to Angular I would recommend using just one module to start with.
To clarify; you should only define a module once by typing angular.module("module_name", []). Notice the [] here. In this array you would put dependencies for the module (if you really wanted the 'thespicy' module you could have included it as a dependency with angular.module("newtest", ['thespicy']). If you later wanted to add a controller to the module you would reference the module with angular.module("module_name") (no []). For example:
// Define a module
angular.module('foo', []);
// Reference the previously defined module 'foo'
angular.module('foo')
.controller('barCtrl', function() { ... });
Here is a working fork of your example: http://plnkr.co/edit/rtUJGeD52ZoatoL3JgwY?p=preview btw.
The nested controller only controls inside the scope of the tag. In this case, it only has access to the scope inside of the h1 tag.
Try this:
<!DOCTYPE html>
<html ng-app="newtest">
<head>
<script data-require="angular.js#*" data-semver="1.3.5" src="https://code.angularjs.org/1.3.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script src="spicy.js"></script>
</head>
<body ng-controller="testController">
<h1>Hello Plunker! {{message}}</h1>
<input type="text" name="firstName" ng-model="thetext">
{{double(thetext)}}
<div ng-controller="controlspicy">
<h1>new test</h1>
<h2>{{greeting}}</h2>
</div>
</body>
</html>
Here's a working plunker of your example: http://plnkr.co/edit/gufbBI4i68MGu8FWVfJv?p=preview
I should point out that you didn't include your controller in your main app.
script.js should start like this:
var app = angular.module("newtest", ['thespicy'])
You have multiple apps
check this plunkr for working nested controllers
<div>
<div ng-controller="testController">
<h1>Hello Plunker! {{message}}</h1>
<input type="text" name="firstName" ng-model="thetext">
{{double(thetext)}}
</div>
<div ng-controller="thespicy">new test
<h2>{{greeting}}</h2>
</div>
</div>
script.js
var app = angular.module("newtest", [])
.controller("testController", ["$scope", function($scope) {
$scope.message = "hola";
$scope.double = function(value){
if (value == null){
return 0;
}
return value*2;
};
}])
.controller('thespicy', ["$scope", function($scope) {
$scope.greeting = "Hello";
}])

Angular JS - Load a template html from directive on click of a button

I am trying to load a HTML template when a link is clicked. I have made a directive that contains templateUrl which loads a HTML file. I am calling a function when a link is clicked that appends a div with our custom directive "myCustomer" to a div already in index.html. whatever i have done so far is shown below, but it doesn't work.
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-example12-production</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.1/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="docsTemplateUrlDirective">
<div ng-controller="Controller">
show
<div id="d"></div>
</div>
</body>
</html>
script.js
(function(angular) {
'use strict';
angular.module('docsTemplateUrlDirective', [])
.controller('Controller', ['$scope', function($scope) {
$scope.showdiv = function(){
$("#d").append("<div my-Customer></div>");
};
}])
.directive('myCustomer', function() {
return {
templateUrl: 'my-customer.html'
};
});
})(window.angular);
my-customer.html
<p>DIV CONTENT</p>
Here is the link i was testing this code here
This is because the angular doesn't bind the directives if you append content like this,
you need to $compile service to do this and this will bind the directives against your $scope
so controller like,
.controller('Controller', ['$scope', '$compile', function($scope, $compile) {
$scope.showdiv = function(){
var compiledeHTML = $compile("<div my-Customer></div>")($scope);
$("#d").append(compiledeHTML);
};
}])
here is the DEMO
OR good to do like this,
use ng-if to create or removing element from html,
try this code
Controller,
....
$scope.anableCustomerDirective = false;
$scope.showdiv = function(){
$scope.anableCustomerDirective = true;
};
HTML
<body ng-app="docsTemplateUrlDirective">
<div ng-controller="Controller">
show
<div id="d">
<div my-Customer ng-if='anableCustomerDirective'></div>
</div>
</div>
</body>
Suggestion
if your main intention is to place a html content after the click, then you can use ng-include here and it will much cleaner and no need of a another directive.
<div id="d">
<div ng-include="templateURL"></div>
</div>
$scope.showdiv = function(){
$scope.templateURL = 'my-customer.html';
};
find the DEMO
Seems like directive is only meant to load template from it.I'd suggest you to use ng-include directive then
Markup
show
<div id="d"></div>
<div ng-include="showDiv ? 'my-customer.html': ''">
The most common way is to use $compile. More info: Dynamically add directive in AngularJS
Then your controller may look like this:
angular.module('docsTemplateUrlDirective', [])
.controller('Controller', ['$scope', '$compile', function($scope, $compile) {
$scope.showdiv = function(){
var el = $compile( "<div my-customer></div>" )( $scope );
$('#d').append( el );
};
}]);
Note that the directive invokation should look like this: <div my-customer>, not <div my-Customer></div> as you have in your code.
when you do it manually with append you actually do not run $apply or $digest so the directive is not run,
can you try to do it with ng-show or ng-if ... e.g
<body ng-app="docsTemplateUrlDirective">
<div ng-controller="Controller">
show
<div my-customer ng-if="showdiv"></div>
<div id="d"></div>
</div>
</body>
this way angular runs the $apply and the directive will be rendered.

AngularJS controller function never called

My angularjs controller function is never called. I see all the js files included in my sources, it's just not ever hitting the initialization of my controller. What is wrong with this code?
eventListCtrl.js:
eventsApp.controller('eventListCtrl', ['$scope', function ($scope) {
// this code is never called
alert('controller initializing');
$scope.name = "Test";
}]);
app.js:
'use strict';
var eventsApp = angular.module('eventsApp', []);
Index.cshtml:
<div ng-controller="eventListCtrl">
<div class="row">
<div class="spann11">
<h2>{{name}}</h2>
</div>
</div>
</div>
<script src="/scripts/vendor/angular.js"></script>
<script src="/scripts/app.js"></script>
<script src="/scripts/controllers/eventListCtrl.js"></script>
You need to do this
<html ng-app="eventsApp">
So you actually activate the module
I want to post my issue/resolution here in case anyone does the same thing as me.
<div ng-controller="coolCtrl" ng-if="VAR">
I was trying to init a controller on an element that didn't get created (because of the ng-if="var" )
facepalm
Wild guess:
angular.module('eventsApp').controller('eventListCtrl', ['$scope', function ($scope) {
// this code is never called
alert('controller initializing');
$scope.name = "Test";
}]);
in your controller file?
<html ng-app="eventsApp">
<div ng-controller="eventListCtrl">
<div class="row">
<div class="spann11">
<h2>{{name}}</h2>
</div>
</div>
</div>
<script src="/scripts/vendor/angular.js"></script>
<script src="/scripts/app.js"></script>
<script src="/scripts/controllers/eventListCtrl.js"></script>
</html>
This should fix it

Categories