Put JavaScript function in Angularjs file - javascript

I have my JavaScript with Angularjs like this :
...
var propertiesModule = angular.module('xxx.properties', []);
propertiesModule.controller('PropertiesCtrl', ['$scope', '$routeParams', 'PropertiesService', 'ApplicationService', 'PlatformService', 'Page', function ($scope, $routeParams, PropertiesService, ApplicationService, PlatformService, Page) {
...
}]);
I want to call a jQuery functionality like this
...
$("input[type=button]").click(function () {
$("#wrapper tr").prettyTextDiff({
cleanup: $("#cleanup").is(":checked")
});
});
...
I put in end of my file but the functionality is not executed, why?

use directives for handling dom. and angular has its own methods for handling dom, using jquery is a bad idea. here is some code to help
app.directive('myDomDirective', function () {
return {
link: function ($scope, element, attrs) {
element.bind('click', function () {
element.html('You clicked me!');
// do your stuff
});
}
};
});
and a link to help you learn
angular directives

Related

AngularJS rootScope.$emit from within Directive

I have a directive for users to like (or "fave") posts in my application. Throughout my controllers I use $rootScope.$emit('name-of-function', some-id) to update user data when they like a new post, as this is reflected throughout my application. But I can't seem to use $rootScope.$emit in the directive. I receive an error
$rootScope.$emit is not a function
Presumably the $rootScope.$on event which corresponds with this command has not been called yet, so this function does not yet exist? What can be done about this? Is there a better way to arrange this?
var module = angular.module('directives.module');
module.directive('postFave', function (contentService, $rootScope) {
return {
restrict: 'E',
templateUrl: 'directives/post-fave.html',
scope: {
contentId: '#',
slug: '#'
},
link: function ($scope, $rootScope, element) {
$scope.contentFavToggle = function (ev) {
contentId = $scope.contentId;
contentService.contentFavToggle(contentId, ev).then(function (response) {
$rootScope.$emit('dataUpdated', $scope.slug);
if (response) {
$scope.favourite[contentId] = response;
} else {
$scope.favourite[contentId] = null;
}
});
};
console.log("track fave directive called");
}
};
});
from controller:
var dataUpdatedListener = $rootScope.$on('dataUpdated', function (event, slug) {
dataService.clearData(slug);
dataControllerInit();
});
How can I access this rootscope function from within the directive? Thanks.
FYI - "link" has been used in the directive because this is related to an instance of an HTML element which will be used a number of times on the page
link has the following signature, there is no need to add $rootScope injection into link function:
function link(scope, element, attrs, controller, transcludeFn) { ... }
Remove it from link and it will work.

Defining angular controllers and component

I'm trying to call a function from within one angular component's controller to another component's controller. I found this answer, but the controllers are defined differently than what is shown in the tutorials I followed, so I'm confused as to how I'm supposed to reference the components and templates.
Here is how I currently define one of my controllers based on the official angular tutorial
angular.
module('moduleName').
component('firstComponent', {
templateUrl: 'url/to/template',
controller: function FirstController($scope) {
//I want to call a function in SecondController here
}
});
//in another component file
angular.
module('moduleName').
component('secondComponent', {
templateUrl: 'url/to/template',
controller: function SecondController($scope) {
//function here which will be called
}
});
Say I re-structure them like in the example I linked above...
var app= angular.module("myApp",[]);
app.controller('One', ['$scope', '$rootScope'
function($scope) {
$rootScope.$on("CallParentMethod", function(){
$scope.parentmethod();
});
$scope.parentmethod = function() {
// task
}
}
]);
//in another file
var app= angular.module("myApp",[]);
app.controller('two', ['$scope', '$rootScope'
function($scope) {
$scope.childmethod = function() {
$rootScope.$emit("CallParentMethod", {});
}
}
]);
How am I supposed to reference each controller's component which they belong to, and their respective templates? I tried to write them like in the example I linked above, but nothing happened. I didn't get any errors, but literally nothing happened. Nothing was displayed on the page. It tried to write to the console, but nothing appeared.
Your second block of code has the right concept, but both controllers need to be instantiated for it to work.
Here's a working JSFiddle. https://jsfiddle.net/reid_horton/rctx6o1g/
When you click the button, the text Hello from callerComponent! appears below it.
HTML
<div ng-app="myApp">
<caller-component></caller-component>
<callee-component><</callee-component>
</div>
JS
var app = angular.module("myApp", []);
app.component("callerComponent", {
template: "<button ng-click='externalCall()'>Click Me!</button>",
controller: function ($scope, $rootScope) {
$scope.externalCall = function () {
$rootScope.$emit("setText");
}
}
});
app.component("calleeComponent", {
template: "<p>{{ myText }}</p>",
controller: function ($scope, $rootScope) {
$rootScope.$on("setText", function () {
$scope.myText = "Hello from callerComponent!"
});
}
});

How do I get an instance of a controller that was created by AngularJS?

I have an app based on Angular which I initialize like this:
myapp.init = (function () {
'use strict';
var angularApp = angular.module('myapp', [])
.directive('homeIterationDirective', function () {
return function (scope, element, attrs) {
var isTopCard = scope.$last ? true : false;
cards.initSingleSwipe(element.get(0), function (event) {
// I want to call indexPageController.onSwiped(event) here!
}, isTopCard);
};
})
.directive('homeDirective', function () {
return function (scope, element, attrs) {
cards.initPanel(element, function (event) {
// I want to call indexPageController.onButtonPressed(event) here!
});
};
});
angularApp.factory('AjaxService', myapp.services.AjaxService);
angularApp.controller('IndexPageController', ['$scope', '$http', '$sce', 'AjaxService', myapp.pages.IndexPageController]);
}());
My controller looks like this:
myapp.pages.IndexPageController = function ($scope, $http, $sce, MyService) {
'use strict';
var somevalue = {};
this.onSwiped = function (event) {
doSomethingWith(event, somevalue);
};
this.onButtonPressed = function (event) {
doSomethingWith(event, somevalue);
};
};
In the 2 directives homeIterationDirective and homeDirective I have 2 callbacks cards.initSingleSwipe and cards.initPanel. Within these callbacks I want to call public methods of my controller but I don't have the instance available that Angular created from IndexPageController. How can I achieve this?
Use (inject) a service (and not a Controller) if you want "to call a public method" from another place, possibly from another Controller.
angularApp.controller('MyController', function ($scope, IndexPageService) {
IndexPageService.blah();
}));
Controller is intended to receive and modify a $scope (adding methods, variables..etc). The $scope can than be used inside the template (html) that use the controller itself.
If you want to call some controller code within the Angular context but in another place, then you should probably move that calling code to a service and then call the service method directly.
But if you want to call that method outside Angular context then, you can achieve that like this:
<div id="foo" ng-controller="IndexPageController">
<!-- code -->
</div>
Now, you can write something like this:
angular.element(document.getElementById("foo")).scope().blah();
I also think you should use a service for this. But if you still need to call one controller from another you can use $controller service
(function() {
var app = angular.module('myApp', ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider.when("/first", {
templateUrl: 'app/view.html',
controller: 'firstCtrl'
}).when("/second", {
templateUrl: 'app/view.html',
controller: 'secondCtrl'
})
.otherwise({
redirectTo: "/first"
});
});
app.controller('firstCtrl', function ($scope) {
$scope.name = "first Controller";
$scope.nameToUpper = function () {
return $scope.name.toUpperCase();
}
});
app.controller('secondCtrl', function ($scope, $controller) {
var newScope = $scope.$new();
$controller('firstCtrl', { $scope: newScope });
$scope.name = newScope.nameToUpper() + 'from second ctrl';
});
}())
and view is
<div>
{{name}}
</div>

AngularJS: How do I call a function defined in a directive's scope from a controller?

I need to call a function which belongs to the $scope of a ng-directive used in my Angular application.
Let's say the directive is defined like this:
.directive('my-directive', ['$document', '$timeout', function ($document, $timeout) {
return {
restrict: 'E',
replace: true,
scope: {
// ....
},
controller: ['$scope', function ($scope) {
$scope.myFunction= function (mouseEnter) {
// ...
};
}
};
}]);
I need to call myFunction from my controller (let's call it my-controller) which is the controller of the view where my directive is placed.
Is it possible to do it? (eventually modifying the directive)
EDIT : The already answered question provided (proposed for edit) is similar to mine by it's not clear to me or it doesn't apparently solve the specific problem I proposed.
EDIT 2: starting from Dan M. answer (without taking mouseenter/mouseleave in consideration. just trying to make the two controllers communicate with each other), I broadcasted my event to my directive's controller through $rootScope (as there is there is no parent-child relation between the two controllers) by:
console.log("let's broadcast the event.."); // this is printed
$rootScope.$broadcast('callDirectiveControllersFunction'); // I even tried with $scope in place of $rootScope and $emit in place of $broadcast
and by receving it (within the directive's controller) by:
var myFunction = function(){
// ...
}
$scope.$on('callDirectiveControllersFunction', function (){
console.log("event received"); // this is not printed
callMyFunction();
});
// I even tried using $rootScope in place of $scope
However in no case (see comments in code) the event is received
You can call a controller function inside the link block. You can also $emit an event in the directive and listen to the it in the controller (maybe there is a use case for that).
It seems that you want to call it on mouseenter. You can do that by binding to the mouseenter event in the directive link. The catch is you need to $apply the changes.
Take a look at the following piece of code, which contains all 3 examples: http://jsbin.com/cuvugu/8/. (also pasted below)
Tip: You might want to pay attention to how you name your directives. To use a directive as my-directive you need to name it as myDirective.
var app = angular.module('App', []);
app.directive('myDirective', function () {
function directiveLink(scope){
scope.$emit('customEvent');
}
return {
restrict: 'EA',
scope: {},
link: directiveLink,
controller: function ($scope) {
$scope.bar = 'bar';
$scope.myFunction = function () {
$scope.bar = 'foobar1';
};
$scope.$on('customEvent', function (){
$scope.myFunction();
});
},
template: "Foo {{bar}}"
};
});
app.directive('anotherDirective', function () {
function directiveLink(scope){
scope.myFunction();
}
return {
restrict: 'EA',
scope: {},
link: directiveLink,
controller: function ($scope) {
$scope.bar = 'bar';
$scope.myFunction = function () {
$scope.bar = 'foobar2';
};
},
template: "Foo {{bar}}"
};
});
app.directive('mouseDirective', function () {
function directiveLink(scope, element){
element.bind('mouseenter', function(){
scope.$apply(function(){
scope.myFunction();
});
});
element.bind('mouseleave', function(){
scope.$apply(function(){
scope.myOtherFunction();
});
});
}
return {
restrict: 'EA',
link: directiveLink,
controller: function ($scope) {
$scope.bar = 'no';
$scope.myFunction = function () {
$scope.bar = 'yes';
};
$scope.myOtherFunction = function () {
$scope.bar = 'no';
};
},
template: "Mouse Enter: {{bar}}"
};
});
I also included an example with a distinct controller in the JS Bin link. That doesn't really change anything, but it seems to be an important part of your question. Here's the code block:
var app = angular.module('App', []);
app.controller('myController', function($scope){
$scope.bar = 'foo';
$scope.myFunction = function(){
$scope.bar = 'foobar3';
};
});
app.directive('lastDirective', function () {
function directiveLink(scope){
scope.myFunction();
}
return {
restrict: 'EA',
scope: {},
link: directiveLink,
controller: 'myController',
template: "Foo {{bar}}"
};
});

Compile directives via service in angularjs

I'm trying to compile directive via angular service but unfortunately it doesn't work.
The idea is to show errors in popups.
I've modified $exceptionHandler service:
crm.factory('$exceptionHandler', function(popup) {
return function(exception) {
popup.open({message: exception});
}
});
The popup service looks like this:
crm.factory('popup', function ($document) {
return {
open: function (data) {
var injector = angular.element(document).injector(),
$compile = injector.get('$compile'),
template = angular.element('<popup></popup>');
// var ctmp = $compile(template.contents());
$compile(template.contents());
$document.find('body').append(template);
}
};
});
And I don't think that this was a good idea to hard code $compile service (but I haven't any ideas how to realize this in angular):
$compile = injector.get('$compile')
Popup directive:
crm.directive('popup', function () {
return {
restrict: 'E',
replace: true,
templateUrl: '/public/js/templates/common/popup.html',
link: function() {
console.log('link()');
},
controller: function () {
console.log('ctrl()');
}
};
});
May be there are some other ways to do this?
Thanks.
You can inject $compile directly into your service, also you're not quite using $compile correctly:
//commented alternative lines for allowing injection and minification since reflection on the minified code won't work
//crm.factory('popup', ['$document', '$compile', function ($document, $compile) {
crm.factory('popup', function ($document, $compile) {
return {
open: function (data) {
var template = angular.element('<popup></popup>'),
compiled = $compile(template);
$document.find('body').append(compiled);
}
};
});
//closing bracket for alternative definition that allows minification
//}]);

Categories

Resources