How to initialize an angularjs module by passing values/configurations - angularjs

I'm new to Angular and I'm from jQuery background.
My question is How to initialize angularjs module by passing values/configurations. Here is the scenario.
We will have core module (which will load/integrate other modules based on the need)
We're planned to create a module for each major feature
We need to load the module's based on the need
The only one approach till now I'm able to figure out is below,
Creating a custom attribute/tag directive
Create a custom controller to initialize the module
Create a new variable in the $scope and specify the configuration options
With this approach I'm able to access the options specified in the controller scope using the link function in the directive. The code is something like below,
// Main angular module
angular.module('myApp').directive('myDirective', function() {
return {
restrict: 'EA',
scope: {
configOptions: '='
},
link: function(scope, element, attribute) {
// configurations will be available in scope.configOptions
console.log(scope.configOptions);
}
};
});
// Module & Controller to initialize the main module.
angular.module('consumerApp', ['myApp']).controller('HomeCtrl', ['$scope', function($scope) {
$scope.configOptions= {
path: "xxxxx",
height: xxx,
width: xxx
};
}]);
// HTML code
<div ng-controller='HomeCtrl'>
<div myDirective></div>
</div>
Is this valid/best approach or do we have better solutions to achieve the same. On further note is there any way available to initialize the app like we do in jQuery.

Related

Angular custom directive not being called

I am new to angular and am currently converting my conventional html/javascript website into an Angular application.
I am stuck on a custom directive where the problem is that it is not rendering in the view.
From reading the angular docs, I understand the camel-casing convention and that if you don't have the 'restrict' property set, Angular will automatically assume that its an attribute so I know that there are no issues there.
Here is how I have structured my directive:
var directives = angular.module('app.directives', []);
directives.directive("dataPercent", [function() {
return {
restrict: 'E',
template: 'Click me to go to Google '
}
}]);
How it is in the DOM:
<data-percentage></data-percentage>
And the reference to the directive in the header of index.html
<script src="assets/directives/dataPercentDirective.js"></script>
Also just in case this is how I init my controllers, directives and services in app.js:
angular.module('app', ['app.controllers', 'app.directives', 'app.services']);
The strange part is that there are no errors displayed in dev tools
Use datPercent as data is reserved keyword
data is reserved keyword.
jsbin http://jsbin.com/yexonayoho/edit?html,js,output

How to extend a bootstrap ui controller

I have included the bootstrap ui module in my angular project and now I want to extend for example the datepicker controller 'UibDatepickerController' in the 'ui-bootstrap-tpls.js' with further functions.
Okay, I could edit the ui bootstrap file, but that is not that what I want.
I want a modularized file (maybe an own directive) so that there are no big problems when a ui bootstrap update is incoming.
Is that possible? What is best practice?
You can try injecting $controller and extending like this:
app.directive('myUiDirective', function ($controller) {
return {
link: function (scope, iElem, iAttr) {
angular.extend(this, $controller('UibDatepickerController', {$scope: scope}));
}
});
However I am not sure if you will be able to get controller from different module (in this case, from ui.bootstrap).

AngularJS - What is expected behaviour of two directives with the same name but in different modules?

Of course, I can check it myself.
It's more conceptual/architectural question and why it was build so.
angular.module('appmodule1').directive('mydir', function(){});
angular.module('appmodule2').directive('mydir', function(){});
so what should we expect from mydir?
UPD:
dependencies between the modules:
angular.module('app',['appmodule1', 'appmodule2'])
or
angular.module('appmodule1', ['appmodule2']);
One trivial thing is that if your module only directly/indirectly loads only one of the module then that directive factory only will be used. But if your question is what if both the modules are loaded say for example angular.module('app',['appmodule1', 'appmodule2']) and your application is bootstrapped with the module app then the directive factories will be added together, i.e directive factories are additive and such component when used will render with both the factories.
angular.module('app1', []).directive('mydir', function() {
return {
restrict: 'E',
link: function() {
console.log("App1");
}
}
});
angular.module('app2', []).directive('mydir', function() {
return {
restrict: 'E',
link: function() {
console.log("App2");
}
}
});;
angular.module('app', ['app1', 'app2']).config(function($provide) {
$provide.decorator('ngRequiredDirective', function($delegate) {
console.log($delegate); //Check the console on the configuration you will see array of 2 configurations
return $delegate;
})
});;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<div ng-app="app">
<mydir></mydir>
<test ng-required="true"></test>
</div>
Generally the scoping, template etc cannot be specified in both (Rules are same as when an element has more than one directives mentioned) and these kind of directives are generally defined in the same module (or even in a different module) with intend and for special purpose. For example angular internally has a directive with the selector select which works along with ng-options directive, now say in your application you want to convert all the select to a bootstrap select option or with ng-repeated material select. You can abstract them out an still create another directive with the selector select and add your logic to render it by parsing the ng-options expression and render the new dropdown.
An example is within angular itself, the way ng-required and other similar directives are implemented, see this answer for example. You can check it out by doing a console log of ng-required directive factory as below.
.config(function($provide) {
$provide.decorator('ngRequiredDirective', function($delegate) {
console.log($delegate); //Check the console on the configuration you will see array of 2 configurations
return $delegate;
})
});
Why it was built?
By bet would be on extensibility and dividing different responsibility in different factories.
So in short if at all you have multiple directive factories for the same selector it should not be accidental, but created with clear purpose, otherwise it could turn out to be a disaster!
It will depend under which module the directive is instantiated. If you're under the appmodule1, the corresponding directive would be used. There would be no conflict here, unless I'm missing something.

How can I use laravel partial view by angular js in templateURL

I want to show a laravel blade view file in angular JS directive by
var commentsApp = angular.module('CommentApp',[]);
commentsApp.directive('commentForm',function(){
return {
restrict: 'EA',
replace: 'true'
templateURL: 'views/comments/comment-form.blade.php'
}
});
I want to use it by angular directive instead of
#include('comments.comment-form')
Where is my problem? How to solve this.
Thank you.
First you must define a route in laravel
Route::get('comment-form', function() {
return view('comments.comment-form');
});
Then you can use it in AngularJS
var commentsApp = angular.module('CommentApp', []);
commentsApp.directive('commentForm', function() {
return {
restrict: 'EA',
replace: 'true',
templateURL: 'comment-form'
}
});
Answer above is a good idea, however i dont like the idea of asking for a template by routing, We would create a route for each component :c . I leave my solution here:
In gulpfile.js inside elixir function add this line:
var elixir = require('laravel-elixir');
elixir(function(mix) {
mix.copy('resources/assets/js/angular/components/**/*.template.html', public/angular-templates');
//Find all files with suffix .template.html
});
As you notice it, i created a folder called 'angular' and then another one called 'components', there we will have our components
Angular-----------------------------
--Components------------------------
----my-component.directive.js-------
----my-component.template.html------
We have to create a global angular variable taking our browser window origin (www.myapp.com, localhost:8000, etc) by doing:
angular.module('myModule',[])
.value('pathAssets', location.origin + '/angular-templates/')
In our templateUrl we will call the template by writting:
templateUrl: pathAssets + '../angular-templates/my-template.html',
I have to say we have to concat our angular files in a file, otherwise it won't work D: if you don't know how to do it, add these lines in your gulpfile.js
mix.scripts([
'../../../bower_components/angular/angular.min.js',
'angular/app.js',
'angular/controllers/**/*.controller.js',
'angular/components/**/*.directive.js',
'angular/bootstrap.js',
], 'public/js/app.js'); //We concatenate angular files saving them in app.js
Finally execute the command 'gulp' in terminal(In our project), it should generate a new folder in public called angular-templates.
That's it :)
(function(angular) {
'use strict';
angular.module('app').component('bringTeamToEvent', {
templateUrl: '/assets/ng/app/team/bringTeamToEvent.html',
bindings: {
hero: '='
}
});
})(window.angular);
Just work from the public directory, no need to compile assets and move if you dont need to.
Then add the # symbol to tell blade to ignore and let angular do its work within the template
<span>Name: #{{ $ctrl.hero.name}}</span>

Angularjs module loading error

I am trying to execute the simplest angular piece of code that is as follows. I have defined ng-app="budgetTracker" in the div tag. Whenever I try to execute the html, it gives me the following error:
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.2.26/$injector/modulerr?p0=budgetTracker&p1=Eā€¦gleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.2.26%2Fangular.min.js%3A18%3A387)
Code:
(function() {
var app = angular.module("budgetTracker", []);
app.directive("categories", function(){
return {
//User Attribute directives for mixin behavior such as a tooltip, else mostly use element directives
//Directive definition object - a configuration that defines how a directive is going to behave
restrict: 'E', // we are declaring a new html element
templateUrl : 'js/templates/categories.html' // url of the template to be injected
};
});
});
Would anyone know why? I am pointing to the google cdn for angular and I am also including the app.js file in the head tag.
I guess you are missing to execute the function in which you have written module.
Change your app.js to
(function(){
var app = angular.module("budgetTracker", []);
app.directive("categories", function(){
return {
//User Attribute directives for mixin behavior such as a tooltip, else mostly use element directives
//Directive definition object - a configuration that defines how a directive is going to behave
restrict: 'E', // we are declaring a new html element
templateUrl : 'js/templates/categories.html' // url of the template to be injected
};
});
})();

Resources