Angular Controller on Custom Directive - javascript

Here is my controllers.js file
(function(ctx,angular){
'use strict';
angular.module('app.controllers')
.controller('SearchMasterController',['$scope',function($scope){
//My Code
}]);
})(window, angular);
And this is my directives.js file
(function(ctx,angular){
function ControllerFunction(){
//My Controller Code
}
var directiveConfig = {
restrict:'E',
templateUrl:'path/to/acco.html',
controller: ControllerFunction
}
angular.module('app.directives')
.directive('acco', function(){
return directiveConfig;
});
})(window, angular);
Now my question is, can I use this acco directive with some different controller. Ideally, is there any way to get it working like
<acco ng-controller="SearchMasterController"></acco> ?
I tried doing,
<acco>
<div ng-controller="SearchMasterController"></div>
</acco>
and it seems to work.
Is it possible to use
<acco ng-controller="SearchMasterController"></acco> ?
The latter alternative looks ugly to me.

nice to heard this type of access, i have tried
<acco>hi{{name1}}
<div ng-controller="SearchMasterController">{{name1}}</div>
</acco>
<acco ng-controller="SearchMasterController">{{name1}}</acco>
<script>
angular.module('myApp', [])
.controller('SearchMasterController', ['$scope', function ($scope) {
//My Code
console.log("search");
$scope.name1 = 'james';
}])
.directive('acco', function () {
return{
restrict: 'E',
templateUrl: 'acco.html',
controller: function($scope) {
//My Controller Code
console.log("cntrlr fn");
$scope.name1 = 'semaj';
}
};
});
</script>
#that time i getting output as
cntrlr fn
search
cntrlr fn
means if we are using like
<acco>hi{{name1}}
<div ng-controller="SearchMasterController">{{name1}}</div>
</acco>
then we can access both controllers but when we are using like
<acco ng-controller="SearchMasterController">{{name1}}</acco>
we can't access SearchMasterController and it's not loaded also..

Yes you can use some different controller for your directive, but there is some best practice
Use controller when you want to expose an API to other directives. Otherwise use link.
The way you tried to use controller doesn't make much sense
<!--here acco and ng-controller both are directives,
in your directive's 'ControllerFunction' and ng-controller's 'SearchMasterController'
has the same controll (scope) for 'acco' rendered html.
In that case your directive's controller overrite ng-controller functionality.
So leave 'ng-controller',
if you need any functionality in your directive
then pass those functionality using =,&,#-->
<acco ng-controller="SearchMasterController"></acco>

Related

How to add a consistent variable or function to every AngularJS $scope?

I made an App (build using AngularJS 1.X) that has a lot of directives, most of which have there own isolated scope. So, for every new $scope i assign Underscore.js + Underscore.string variables _ and s to them, like so:
controller: function($scope){
$scope._ = _;
$scope._s = s;
$scope.foo = 'my-example-here';
}
Then do some cool stuff like this within there isolated scope templates:
<div ng-bind='s.humanize(some_id)'></div> # output: "My example here"
Unfortunately you cannot access global variables in these scopes.
So, ultimately, how to add a consistent variable or function to every AngularJS $scope?
Try this:
app.controller('MyCtrl', function($rootScope) {
$rootScope.derp = "foo!";
});
app.directive('myDir', function($rootScope) {
return {
scope { ... },
controller: function($rootScope) {
console.log($rootScope.derp);
}
};
});
Make sure to put ng-controller="MyCtrl" directive somewhere on the parent DOM element of your custom directive like so:
<div ng-controller="MyCtrl">
<div my-dir></div>
</div>
Try it please.
EDIT
Also, you can use constants as described by #georgeawg in comment.

JS - AngularJS - Get data of an directive from a controller

I´ll give my best to make my problem understandable:
I have a directive. This directive handles/alters also some data it displays. Now I was wondering how I can access these data from a parent scope e.g. the controller. I am currently getting access to the scope by selecting the element and ask for the corresponding scope:
element.scope()
It works fine but it occurs to me that this is kind of a - lets say - unconventional or odd way to get the scope of an directive.
I apologize for my english (I still practicing) and hope you guys can help me. Thank you in advance :)
OK, Based on the comments your directive is some kind of a form. There are two approaches for controlling the data inside a directive:
Parent controller of a directive should control the data. In that case, Data of each directive is unique and does not share between all directives.
The directive itself should control the data. Which it means the data will be shared in all directives, and if You change one, another will be changed too.
I go with the solution number 1 which is more preferable in my guess. Let's say your template of directive is something like this,We call it template.html:
<form name="directive_from" ng-submit="submit_form()">
<input type="text" ng-model="form.name" name="username" placeholder="username"><br>
<button type="submit">Submit</button>
</form>
Because of the time,I skipped validation but you can do that easily :)
And the directive:
angular.module('app')
.directive('formDirective',function(){
return {
restrict: 'E',
templateUrl: 'template.html',
scope: {
form: '=formData',
submit_form: '#formFunc'
},
controller: ['$scope', function($scope) {
//some extra logic or binding if you need
}
}
})
OK,Now our directive which we call it formDirective accepts two parameters:
formData which is an object and holds user inserted data.
formFunc which is a function for submitting the form.
Now parent controller:
angular.module('app')
.controller('MainCtrl', ['$scope', function($scope) {
$scope.form_object = {};
$scope.submit_it = function() {
//Do whatever you like with the $scope.form_object
}
}
And let's see the view:
<div ng-controller="MainCtrl">
<form-directive form="form_object" form-func="submit_it()"></form-directive>
</div>
That's it! It's so simple example that I believe you can customize it by your needs,But the main logic for controlling the data is something like that. for example you can pass a function for ng-change on the input field or add more input fields or...
#lilly: I think you you are looking for data exchange between the parent scope and isolated scope which is possible via '='
Here is the working fiddle
angular.module('App', [])
.controller('Main', ['$scope', function ($scope) {
$scope.exchange = {};
$scope.exchange.value = "initialized by controller";
}])
.directive('inputValue', function($timeout) {
return {
restrict: 'A',
scope: {exchangeValue: '='},
link: function(scope, element, attrs) {
$timeout(function(){
scope.exchangeValue="changed by directive";
},2000);
}
};
});
http://jsfiddle.net/tiru/dJty6/43/

angularjs routing behaviour of content and function calls

I'm new to Angular.js which is why I have a basic question regarding routing. I figured out how to create routes and inject specific .htmls by $routeProvider
var app = angular.module('test', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'routes/view2.html'
});
});
but what I really don't get is how content or function of view2.html are handled in Angular.
Lets take view2.html. It has a <p> with some text in a specific color. Nothing to special. But also it has a little slideshow which is called by $('slideshow').cycle() function.
All what happens is it displays me the <p> tag in a different color and no slideshow function is called on my rootsite of the app.
Could you give me some approach how to actually solve this?
Thanks
Just load required view and then compile it. During compilation Angular processes all directives in view.
If you want to do this proper(Angular) way you should put such code like $('slideshow').cycle() inside of directive. And then use it like
<div my-slideshow=""></div>
angular.module('myModule', [])
.directive('mySlideshow', [function () {
return {
restrict: 'A',
link: function (scope, element) {
element.cycle();
}
}
}]);
Directives documentation
Much more comprehensive documentation

Is it good to have main controller in Angular?

I dont know if this is a good practice... I have a controller defined in route config but because my HomeCtrl is in ng-if statement he cannot listen for loginSuccess so I made MainCtrl which listens for loginSuccess and reacts appropriately. This code works just fine but this smells like a hack to me. Should I remove MainCtrl and make it a service? If so some example would be really great.
Index.html
<body ng-app="myApp" ng-controller="MainCtrl">
<div ng-if="!isLoged()">
<signIn></signIn>
</div>
<div ng-if="isLoged()">
<div class="header">
<div class="nav">
<ul>
<li class="book">navItem</li>
</ul>
</div>
</div>
<div class="container" ng-view=""></div>
</div>
</body>
App.js
angular.module('myApp', [])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'HomeCtrl'
})
.otherwise({
redirectTo: '/'
});
})
.controller('MainCtrl', function ($scope) {
$scope.user = false;
$scope.isLoged = function(){
if($scope.user){
return true;
}else{
return false;
}
}
$scope.$on('event:loginSuccess', function(ev, user) {
$scope.user = user;
$scope.$apply();
});
})
.controller('HomeCtrl', function ($scope, $location) {
//this is home controller
})
.directive('signIn', function () {
return {
restrict: 'E',
link: function (scope, element, attrs) {
//go to the server and then call signinCallback();
}
};
})
.run(['$window','$rootScope','$log',function($window, $rootScope){
$window.signinCallback = function (res) {
if(res){
$rootScope.$broadcast('event:loginSuccess', res);
}
else{
$rootScope.$broadcast('loginFailure',res);
}
};
}]);
I start all of my Angular projects with:
<html ng-app="appName" ng-controller="appNameCtrl">
The use of a "global" controller may not be necessary, but it is always nice to have it around when a need arises. For example, I use it in my CMS to set a binding that initiates the loading of everything else - so all the sub controllers are loaded because of it. That isn't violating separation of concerns because the global controller's concern IS to facilitate the loading of other controllers.
That said, just be sure to keep things as modular/separated and reusable as possible. If your controllers rely on the global controller's existence in order to function, then there is an issue.
In my opinion angular js' power comes with separating out clearly the different controllers directives, services, resources etc. Ideally controllers are linked to templates or partials and are used to update the front end and make calls to services or resources. The sooner you start making these separations the sooner you will start making clean and scalable apps that other developers can quickly make sense of. For app structure I would highly recommend you look into either of these two tools:
Lineman.js
and
Yeomann
The lineman site actually has a really good round up of how the two differ, if you scroll down.
In your scenario there are many ways to link controllers or make function calls that are in different scopes. You can either create a service that injects to your controllers or you can use $emit and $on to set up notifications in the app eg:
In controller A
$rootScope.$on('myNotifier:call', function() {
myFunction();
});
And in Controller B or any other controller you could call myFunction() with:
$scope.$emit('newPatientModal:close');

Right place to detect browser and show/hide a div

I want to show a div (using ng-if or ng-show/hide) if the user opens the page in a certain browser (in this case, chrome/chormium), and I'm not really sure where is the best place.
The javascript code looks like this: /chrome/i.test( navigator.userAgent ), but where is the best place to place it? In a filter? In a controller? In a directive?
Check the below detailed browser detection script
http://www.quirksmode.org/js/detect.html
I will suggest you to use "Directive" or "Filter"
Working Demo
Below is the filter example code:
angular.module('myApp', []).filter('checkBrowser', function(){
return function(){
return /chrome/i.test(navigator.userAgent)
}
})
Template Code:
<div ng-show="{{''|checkBrowser}}">Hello</div>
You could assign your condition to a scoped variable inside the controller:
angular.module('myApp', []).controller('MyCtrl', ['$scope', function( $scope ) {
$scope.isChrome = /chrome/i.test(navigator.userAgent);
});
Then inside your view:
<div data-ng-show="isChrome">You're running Chrome!</div>
If you need a variable that's available to any controller, use a Service:
angular.module('myApp', []).factory('UAService', function() {
return {
isChrome: /chrome/i.test(navigator.userAgent)
};
});
Then from a page-level controller (i.e., one assigned to a top-level element such as <body>) or any other controller, inject your service:
angular.module('myApp', []).controller('MyCtrl', ['$scope', 'UAService', function( $scope, UAService ) {
$scope.UAService = UAService;
});
Your service would now be accessible from any scope within the scope created by your page-level controller:
<div data-ng-show="UAService.isChrome">You're running Chrome!</div>

Categories

Resources