I have two js files, app.js and datepicker.js. I have nothing to do with the html file here. There is a javascript function called clickApply() in datepicker.js. I want to call another submitDetails() function which is inside the app.js file from the clickApply() function. How to do it?
angular.module('ctrl').controller('MyCtrl', ["$scope","$rootScope", function($scope, $rootScope){
$rootScope.submitDetails=function()
}]);//inside app.js
clickApply: function(e) { //inside datepicker.js
angular.element('#span').on("click",submitDetails());
this.hide();
this.element.trigger('apply.daterangepicker', this);
}
No one prefer executing the angular functions outside of angular scope. If you want to implement a jQuery or any other external plugin in AngularJS, wrap it in directive and use it.
Below code is used for debugging purpose only.
Change your clickApply function signature to below:
For accessing scope you can use angular.element(element).scope()
For rootScope you can use angular.element('body').scope().$root`
clickApply: function(e) { //inside datepicker.js
angular.element('#span').on("click", function(e) {
// if you want to access rootScope
var rootScope = angular.element('body').scope().$root;
rootScope.submitDetails();
// if you want to access current scope
// var scope = angular.element(e.target).scope();
// scope.submitDetails();
});
this.hide();
this.element.trigger('apply.daterangepicker', this);
}
Related
$I have a custom javascript object, that can fire events.
I would like to access the angular $scope inside the event-handler, but I have read somewhere that using angular.element(...).scope() is not good, because it's only meant for testing.
My other idea was to register the handle on my object inside the controller, but this is not working (looks like $scope.somevalue gets set, but I don't think $scope is the same object).
I have found many answers here on Stack Overflow for similar questions, but they all seem to be using directives. All I want is to get a value from the object when it's updated, and display it.
Here are the two ways I have tried.
var myObj = GetMyObjInstance();
// Working, but apparently it's not good practise to call .scope() on an element.
myObj.onUpdated = function(){
console.log("myObj updated");
var v = myObj.getValue();
var controllerDiv = document.getElementById("controller");
var $scope = angular.element(controllerDiv).scope();
$scope.apply(function(){
$scope.someValue = v;
});
}
// Tried to do this, thinking i would get closure on the scope.
angular.module('myApp', []).controller('controller', function($scope){
myObj.onUpdated = function(){
console.log("myObj updated"); // Gets logged to console...
var v = myObj.getValue();
$scope.somevalue = v; // ... but somevalue does not get displayed.
$scope.apply(); // Error, says it's not a function, so maybe this is not the right object?.
}
});
Use AngularJS directives to handle events and update scope.
app.directive("xdEvent", function() {
return linkFn(scope, elem, attrs) {
elem.on("event", function(e) {
scope.$eval(attrs.xdEvent, {$event: e});
scope.$apply();
});
};
};
USAGE
<div xd-event="fn($event)"></div>
I think using a Service instead of a controller is a better practice. You can call a service from outside javascript with the injector like explained in this thread :
Call angularjs service from simple js code
If it is still important for you to access this variables from controller, you can use $watch to tell your controller to update itself when the service variables change.
Hope this help.
A+
I have a little trouble with passing value from one function to another in one angular controller.
i have event
onTimeRangeSelected: function (args) {
$scope.dayPilotCal.clearSelection();
$scope.createNewEventModalWindow(args);
},
event call function
$scope.createNewEventModalWindow = function(args)
{
console.log('create new event dialog');
$rootScope.newEvent.start = args.start.value;
console.log($rootScope.newEvent.start);
ngDialog.open({
......
});
}
than i handle dialog confirm button click event
<button
type="button"
class="ngdialog-button ngdialog-button-primary"
ng-click="btnCreateEventClicked()"
>Create</button>
and call function
$scope.btnCreateEventClicked = function(){
console.log('btn create event clicked');
ngDialog.close();
console.log($rootScope.newEvent.start);
};
so that my problem - in first case console.log($rootScope.newEvent.start); print to console real date. But in the second function console.log($rootScope.newEvent.start); print into console 'undefined' value.
all code are in the same controller. And in the first lines of controller i define my global variable $rootScope.newEvent={};
Please help me in that problem.
Global variables makes testing the code really difficult. Because any function can have access to the global scope. In your example I would assume their is another part of your coding that changes $rootScope.newEvent.
If this variable has to be globally available I would suggest to use a service.
If their is no need for this var to be globally accessible, than just change $rootScope.newEvent to $scope.newEvent.
My goal is to create an Angular module that displays popup dialog messages. This module contains a directive (HTML, CSS and JavaScript) containing the internal logic (and markup and styles). Plus there's a service (factory) which acts as an API that can be used by other services.
Now this service of course has an openDialog() function which should insert the dialog directive into the DOM and present it to the user.
All solutions to this problem I have found so far make use of the $compile function. But it needs scope as a parameter. In a service where there's no scope though. They only exist in controller or link functions.
The reason I chose this implementation is for separation of concerns (directive's link and controller for internal usage, factory for external usage because it can be dependency injected). I know I could pass the scope when calling the function like this:
popupDialogService.openDialog({ /* options */ }, $scope);
But I don't see the point. It doesn't feel right. What if I call that function from inside another service which doesn't use scope either?
Is there a way to easily put the directive into the DOM from inside the service function or is there a better way to solve this problem?
Another solution I'm thinking about is calling a function of the directive's controller from inside the directive's factory. Is that possible?
Code
popupDialog.directive.js
angular.module('popupDialog').directive('popupDialog', directive);
function directive() {
return { ... };
}
popupDialog.service.js
angular.module('popupDialog').factory('popupDialogService', factory);
function factory() {
return { openDialog, closeDialog }; // *ES2015
function openDialog(options) {
// this function should put the `popupDialog` directive into the DOM
}
function closeDialog() {
// and this one should remove it
}
}
some.random.service.js
angular.module('myApp').factory('someRandomService', factory);
factory.$inject = ['popupDialogService'];
function factory(popupDialogService) {
return { clickedButton };
function clickedButton() {
popupDialogService.openDialog({ /* options */ });
// Sample implementation.
// It shouldn't matter where this function is beeing called in the end.
}
}
I know I could pass the scope when calling the function ... And it doesn't feel right.
Well you anyway need scope for dialog HTML content, Angular needs to compile and render it in some scope, right? So you have to provide scope object for your template somehow.
I suggest you to take a look at popular modal implementations like they do it, for example Angular UI Bootstrap's $modal or this simple one I was creating for my needs. The common pattern is passing scope parameter with modal initialization or use new child scope of the $rootScope for dialog. This is the most flexible way that should work for your both cases.
After all, it's not necessarily has to be real scope instance. You can even make your service accept plain javascript object and use it to extend new $rootScope.$new() object with.
What scope is a function defined inside an angular js controller, part of?
.controller('MyCtrl', ['$scope', '$location', function($scope, $location) {
function log() {
console.log('Vanakkam Ulagam');
}
var functionToCall = 'log';
????????[functionToCall]();
}])
I tried MyCtrl, this and $window. I can access the function by namespacing it like so functions.print = function() and then using functions[functionToCall]().
I am more interested in accessing the function without namespacing it. Is it possible? If not, why?
i think this is solution for this question
var f;
var a = angular.module('MyApp',[]);
a.controller('MyCtrl', ['$scope', function ($scope) {
$scope.log=function(){
console.log('test');
}
f=$scope.log;
});
and this function useable to element html for example
<button ng-click='log()'></button>
or
<button onclick='f()'></button>
If you're just trying to access global functions in your controller code, window (or $window if it's properly injected) should work fine:
$scope.alert = function(text) { window.alert(text) }
To be extra sure this works in other environments you could manually bind it in a self-invoking anonymous function:
(function(global){ //make the global scope assigned to the variable global
app.controller('MyCtrl',['$scope',function($scope){
$scope.alert = global.alert;
}]);
)(this); //this is the global object when this is evaluated
If you want to do anything inside an expression on a DOM element (such as ng-click), it's important to realise that angular expressions are evaluated by Angular's own expression evaluator (namely through $scope.$eval). So if something is not attached to a scope, it cannot be used in an angular expression.
However, if you were to do something like attach the global object to the scope, then everything is fair game. This really isn't recommended (I think there's no real reason to do this, and its better to manually define functions you need), but :
$scope.global = window
Inside your controller definition should work. You can then do things like ng-click="global.alert('Yo SO!')" in your DOM without issues.
For better testability you could use $window (you said you tried it and it didn't work... are you sure you injected it properly? Look at the example in the documentation carefully). But like I said, if you're attaching the global object to the scope you're opening Pandora's Box.
I am learning angularjs and a bit confused. I am creating an angular module and controller functions like this:
var mapApp = angular.module("mapApp", []);
mapApp.controller("mapController", function($scope) {
$scope.save = function() {
//do domething
};
});
And I have other functions out of the controller.
function onMapClickEvent(e) {
//do domething
}
When map clilcked, I want to populate angular save function. Is this possible.
I asked this because sometimes we need to work with more then one API. AngularJS and Google Maps API. One API function need to populate other API.
You can cast DOM element to Angular element in this way:
angular.element(DOM)
And get the current scope of DOM by invoking scope()
angular.element(DOM).scope()
Then you can access any member of this scope, in your example: save()
I implemented a simple example, you could try it:
HTML
<div ng-controller="myCtrl">
<button id="testBtn" onclick="onClick(this)">test</button>
</div>
JS
angular.module("app",[])
.controller("myCtrl",function($scope){
$scope.angularWorldFunction = function(){
console.log("message from angular world");
}
});
function onClick(target){
angular.element(target).scope().angularWorldFunction();
}
Here is jsFiddle demo
Hope this helpful.