Angular custom directive not being called - angularjs

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

Related

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 to make ui-sref work inside JQuery loaded HTML DOM

I am new to Angular JS. What I am doing is to bind ui-sref on JQuery loaded data.
All the JQuery plugins and rest of Angular is working perfectly fine. What I have for now looks like:
app.controller("FeedController", ['$scope', '$http', '$compile', function($scope, $http, $compile) {
var feed = this;
feed.years = [];
feed.getYears = function() {
$http.get('/timeline/years').success(function(data) {
feed.years = data;
});
};
feed.getYears();
$scope.$watch('sliderWrapper', function() {
applyTreemap(); // jquery treemap layout plugin
applyKnob(); // jquery knob plugin
});
// I was trying to compile externally loaded DOM by that plugin here.
// Didn't figure out how to do it.
$scope.refresh = function() {
// #slider is main content wrapper
$compile( $("#slider").html())($scope);
};
}]);
Please don't suggest to use AngularJS instead of JQuery. Actually this is a Treemap Layout plugin and already integrated into existing website.
Okay so $compile works as in my code but there are some problems I faced. Here's one. Consider the following code.
<div id="slider">
<div ng-repeat="slide in slides">
<!-- html loaded by jquery ajax will go here -->
</div>
</div>
In angular I was doing
$compile( $("#slider").html())($scope);
So, I was compiling html of #slider in angular and it already has angular bindings besides ajax loaded content. So angular compiler will re-render them and you will run into problems.
So keep in mind that you never $compile html that already has angular bindings.
So I solved my problem by putting
href="#/path/to/state"
instead of doing
ui-sref="home.child()"
into ajax loaded conent.
Sometimes you know something and its not in your mind when you are stuck. :-D

How to initialize an angularjs module by passing values/configurations

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.

AngularJS isolated directives inheriting surrounding or parent scope

I have put up my code at jsbin: http://jsbin.com/fewom/1/edit
If any one can guide me, what am I doing wrong there. I have specified scope to be isolated inside myDirective with scope: {} but still when i write myProperty inside my directive in html I am able to read myProperty.
I was using AngularJS https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js
When i changed my library to it started to work,
https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.3/angular.js
then I have tried,
Angular JS version 1.2.16
https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js
and
Angular JS version 1.3.0-beta.5
https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.5/angular.min.js
and the problem for isolated scoping shows up again.
You don't have a controller, so nothing ties your directive to your html.
Change your js to this (I just added a blank controller):
angular.module('myApp', [])
.directive('myDirective', function() {
return {
restrict: 'A',
scope: {}
};
})
.controller('ctrl', function (){
});
and in your html, change to this (referenced the controller):
<html ng-app="myApp" ng-controller='ctrl'>

Can't bootstrap an angular app

I was following the angular docs and other links in order to create a "component" with angular inside a rails-based project.
The problem is that I can't correctly initialize the app, and instead I got two identical errors
Uncaught Error: No module: testApp0
Uncaught Error: No module: testApp0
In the following jsfiddle I try to show you my point http://jsfiddle.net/d8Lyu/
I'm pretty new in angular and the official documentation isn't very helpful
You are almost here! Just remember angular is modular and every module need to be declared with an angular.module('my_module_name', ['my_modules_dependency']).
Just refactor your code like that :
angular.module( //this is your app module
'testApp0',
['testApp0.controllers'] //your app need your controller as a dependency to works
);
angular.module( //this is your controller module
'testApp0.controllers',
[]
).controller('sliderCtrl', ['$scope', function($scope) {
$scope.greeting = "hellow" //you pass a gretting variable to your template
}
])
An other thing : you declare a gretting variable in your controller but acces it with user.hellow in your template. Just put {{ gretting }}.
One last thing, in the
frameworks and extensions
of fiddle change 'onLoad' to 'in body', you don't want your angular app to be ready before the DOM.
If you plan to use angular, look at : angular-app. The tutorial app can't be trusted for serious angular developement.
Use this jsfiddle as a reference: http://jsfiddle.net/joshdmiller/HB7LU/
You need to add an external resource, change settings in the 'fiddle options' section and the 'frameworks and extensions' section.
Once everything is setup you can create your angular in the javascript pane likeso:
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.name = 'Superhero';
}

Resources