AngularJS : minification issue in directive - angularjs

I have yet another issue with minification. This time it's because of the $scope service passed to the directive's controller. See below code:
angular.module('person.directives').
directive("person", ['$dialog', function($dialog) {
return {
restrict: "E",
templateUrl: "person/views/person.html",
replace: true,
scope: {
myPerson: '='
},
controller: function ($scope)
{
$scope.test = 3;
}
}
}]);
If I comment out the controller part, then it works fine.
As you can see, I've used the array declaration for the directive, so the $dialog service is known to Angular even after minification. But how am I supposed to do it for the $scope service on the controller ?

You need to declare a controller as follows:
controller: ['$scope', function ($scope)
{
$scope.test = 3;
}]
Full example here:
angular.module('person.directives').
directive("person", ['$dialog', function($dialog) {
return {
restrict: "E",
templateUrl: "person/views/person.html",
replace: true,
scope: {
myPerson: '='
},
controller: ['$scope', function ($scope)
{
$scope.test = 3;
}]
}
}]);
A solution provided by #Sam would work to but it would mean exposing directive's controller to the whole application which is unnecessary.

ok, I ended up creating the controller in a separate file :
angular.module('person.controllers').controller('personCtrl', ['$scope', function ($scope) {
$scope.test = 3;
}]);
then in the directive, I assign the controller by name:
controller: 'personCtrl'
Not sure it's the best way. It looks clean though. What do you think ?

Related

Change Directive variable inside a directive is not working

I am trying to change a controller variable inside a directive and this is my code:
the main controller is :
angular.module("app").controller('vehicleManagementController', ['$scope', 'toastr', '$filter' ,
function ($scope, toastr, $filter) {
.....
$scope.filteredDevices = //Some List
$scope.allDevices = [];
}
}]);
and the directive is :
angular.module('app').directive('advanceSearchDirective', ['deviceAdvancedSearchService', 'mapService', function (deviceAdvancedSearchService, mapService) {
return {
restrict: "E",
controller: 'myDirectiveController',
scope: { filteredDevices: '=filteredDevices' },
templateUrl: '/app/templates/advanceSearchDirective.html'
};
}]);
angular.module("app").controller(myDirectiveController( $scope) {
$scope.search = function() {
$scope.filteredDevices = [];
$scope.$apply();
}
});
the thing is it faild to run the apply() method through this error.
and here how i am using it :
<advance-search-directive filtered-devices="filteredDevices" model="$parent"></advance-search-directive>
I have access to $scope.filteredDevices inside the directive controller but when i change its value it doesn't change in the main controller. what am I doing wrong?
if you want to save the changes on the parent controller scope you should use
scope:false,
change the directive to :
return {
restrict: "E",
controller: 'myDirectiveController',
scope: false,
templateUrl: '/app/templates/advanceSearchDirective.html'
};
here is an useful article .

Directives in AngularJS

Hi I am trying to learn AngularJS Directives and I came really close but would like to extend my learning by cleaning and de-coupling my directive code.
Directive:
app.directive('ngSparkline', function () {
var url = "http://api.openweathermap.org/data/2.5/forecast/daily?mode=json&units=imperial&cnt=14&callback=JSON_CALLBACK&q=";
return {
restrict: 'A',
require: '^ngCity',
transclude: true,
scope: {
ngCity: '#'
},
templateUrl: 'app/partials/weatherTemplate.html',
controller: ['$scope', '$http', function($scope, $http) {
$scope.getTemp = function(city) {}
}],
link: function (scope, iElement, iAttrs) {
scope.getTemp(iAttrs.ngCity);
scope.$watch('weather', function (newVal) {
if (newVal) {
var highs = [];
angular.forEach(scope.weather, function (value) {
highs.push(value.temp.max);
});
chartGraph(iElement, highs, iAttrs);
}
});
}
};
});
As you can see I am not trying to write inline template rather use templateUrl. Now the problem is for the controller when I try using a .js controller instead of writing the controller code inline, I receive an error. How do I achieve this.
I tried:
I tried passing
controller: '#',
name: 'ctrl'
and I pass the 'ctrl' as:
<div ng-sparkline ng-city="San Francisco" ctrl="weatherController"></div>
it gives me controller not found. My project structure is something like below.
What am I doing wrong?
Is there a better/correct way of doing this?
Please suggest.
Note: I am learning this exercise from "http://www.ng-newsletter.com/posts/directives.html"
Why not just specify ng-controller on your element? If WeatherController is defined somewhere else then it doesn’t affect your directive definition, just leave the controller out of there.
<div ng-sparkline ng-city="San Francisco" ng-controller="WeatherController"></div>
Provided somewhere you do have the controller defined like
app.controller('WeatherController', ['$scope', '$http', function ($scope, $http) {
$scope.getTemp = // …
}]);
(BTW, if you noticed, the AngularJS convention is to name controllers in UpperCase fashion.)

Controller executes twice, what is the best solution?

I know where the problem is i just don't know how to go about fixing it. I have two directives that call the same controller and after research i found out its a bad thing and i should use a service or something.
Now i believe i have to communicate between both these controllers. Every time i do a console.log inside the controller it runs twice.
What should i do?
Directives
app.directive("sidemenu", function() {
return {
restrict: 'A',
templateUrl: 'partials/sidemenu.html',
scope: true,
transclude : false,
controller: 'taskbarController'
}
});
app.directive("taskbar", function() {
return {
restrict: 'A',
templateUrl: 'partials/taskbar.html',
scope: true,
transclude : false,
controller: 'taskbarController'
}
});
Controller:
app.controller("taskbarController", ['$scope', 'authData', '$location', 'projectsModal', 'sendMessageModal', 'Poller',
function ($scope, authData, $location, projectsModal, sendMessageModal, Poller) {
$scope.inbox = Poller.msgdata;
$scope.project = Poller.newdata;
$scope.projects = Poller.projects;
$scope.messages = Poller.messages;
console.log($scope.inbox);
$scope.sendMessage = sendMessageModal.activate;
$scope.showModal = function() {
projectsModal.deactivate();
projectsModal.activate();
};
$scope.logout = function () {
authData.get('logout').then(function (results) {
authData.toast(results);
$location.path('login');
});
}
authData.get('session');
$scope.toggle = function(){
$scope.checked = !$scope.checked
projectsModal.deactivate();
sendMessageModal.deactivate();
}
}]);
You could still use controller (rather then service) as long as you are using it to bind the view (for e.g.) If you want to make a webservice call (for e.g.) then I would use service.
Thing you need to think about is that do you need two directive to share same service or just scope? If they (directive) are functionally different then use separate service/contr (Single Responsibility Principal) and if they have some shared data/scope then think about how to cater for that.If you want to share scope between controllers then you can use service which gets injects into the controller.

How do I use array syntax for dependency injection with a directive controller?

I want to be able to specify the controller of my directive with an inline function, but I also want to use ng-strict-di. What syntax is required to do this?
(function(){
angular.module("myAngularModule")
.directive("myDirective", function(){
return {
restrict: 'E',
templateUrl: "templates/my-template.html",
link: function ($scope, element, attrs) {
// ...
},
// This causes an ng-strict-di exception because I'm using implicit annotation for the dependencies - what is the correct syntax?
controller: function($scope, myService) {
// ...
}
};
})
// This syntax is fine
.controller("myWorkingController",["$scope","myService", function($scope, myService){
// ...
}]);
});
Just because the controller is anonymous doesn't meant the syntax changes. Pass an array like you would any other controller assignment. Angular will understand.
controller: ["$scope","myService", function($scope, myService){
// ...
}]
Inject the service in to your directive as, its something like injecting into the controller,
.directive("myDirective", function(myService){
and remove it from the controller.
.directive("myDirective", function(myService){
return {
restrict: 'E',
templateUrl: "templates/my-template.html",
link: function ($scope, element, attrs) {
// ...
},
controller: function($scope) {
// ...
}
};
})
then myService can be access in the controller of the directive.

In angular, how do you provide a controller's argument list from within a directive definition?

I'm trying to follow the best practice of providing an argument list when defining a controller, like this:
angular.module("myApp", [])
.controller("myCtrl", ["$scope", function ($scope) {
// stuff accomplished.
}];
However, I'm not sure how to provide this argument list when the controller is embedded in a directive definition:
angular.module("myApp", [])
.directive("myDirective", function () {
return {
restrict: 'E',
replace: true,
template: '<div>{{ name }}</div>',
controller: function($scope) {
// stuff accomplished.
$scope.name = 'Louis';
},
});
Same way as usual!
controller: ['$scope', function($scope){...}]

Resources