Directive for dynamically adding JavaScript files - javascript

Is it possible to use ng-repeat to dynamically add script files to my html file?
I have a directive like below:
angular.module("app").directive("scriptLoader", function($compile) {
return {
template: "<script ng-repeat='s in files' src={{s}}></script>",
scope: true
}
});
Meanwhile files is a scope variable in my controller:
$scope.files = ["test.js", "script.js"];
And I get the html rendered as:
<script-loader class="ng-scope">
<script ng-repeat="s in scripts" src="test.js" class="ng-scope"></script>
<script ng-repeat="s in scripts" src="script.js" class="ng-scope"></script>
</script-loader>
But it doesn't work since whenever I try to invoke a method from the loaded files, it just says the method is not defined.
I'm just curious why can't I load script like this. Please help!

Related

Loading external scripts within angular html views

I have signed up to a paid version of Polldaddy and was provided this script tag (minus the proper id).
<script type="text/javascript" charset="utf-8" src="http://static.polldaddy.com/p/0000000.js"></script>
This script has to be loaded within a div in a view of mine - and it is not working. Does angular have an issue with loading scripts within a view? Is it possible? If so, could you help me understand how to do it please?
Let me know if you need more info.
Thanks
You can't load a script inside an Angular app due the Angular script directive, so you need to create your own directive.
Something like this:
function polldaddy() {
var injectScript = function(element) {
var scriptTag = angular.element(document.createElement('script'));
scriptTag.attr('charset', 'utf-8');
scriptTag.attr('src', 'http://static.polldaddy.com/p/0000000.js');
element.append(scriptTag);
};
return {
link: function(scope, element) {
injectScript(element);
}
};
}
angular
.module('myApp')
.directive('polldaddy', polldaddy);
and then in your HTML:
<div polldaddy></div>

Adding angular directive with javascript files as package

I am writing a directive that I want other people to reuse.
The problem I encounter is that my directive has several js files it uses, and if I want others to use it, they need to add the js files explicitly.
Is there a way to make the directive include those files so that other will only have to add the directive file?
The way it works today is by adding the js files in the main head html file.
Can I use tamplateUrl to load the js files? Iv'e seen in THIS post that loading scripts creates some problems.
Concrete Example:
index.html:
<body data-ng-app="example">
<test-dir></test-dir>
</body>
index.js:
(function(angular){
var app = angular.module('example', []);
app.directive('testDir', function(){
return{
restrict: 'E',
templateUrl: 'test-me.html'
}
});
})(window.angular);
test-me.html:
<script type="text/javascript" src="test.js"></script>
<div> TEXT </div>
test.js:
function testMe() {
console.log('blah');
}
This format will call the directive and I will see the div TEXT text. BUT, I can't call the function testMe and I don't see any transfer in the network for test.js which is included in the directive's template.
How can I make it work?

Simplest way to use ng-include

I have been trying to write a simple angular.js app, that includes another file using ng-include. I must have done something/missed something so that the included file does not get included. I must be doing something fundamentally wrong but can't see what it is.
Here is Index.html
<!DOCTYPE html>
<html>
<head ng-app="app">
<title>Demo</title>
<script data-require="angular.js#1.2.0" data-semver="1.2.0" src="http://code.angularjs.org/1.2.0/angular.js"></script>
<script data-require="angular-resource#1.2.0" data-semver="1.2.0" src="http://code.angularjs.org/1.2.0/angular-resource.js"></script>
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<div ng-controller="appctrl">
<h1>Airports</h1>
<div ng-include="'extra.html'"></div>
<h1>Airports</h1>
</div>
</body>
</html>
file extra.html contains the element to be included
<h2>Inside</h2>
and script.js is the file to initialise angular
(function () {
'use strict';
var app = angular.module('app', []);
app.run(['$route', function ($route) { // Include $route to kick start the router.
}]);
angular.module('app').controller('appctrl', [function AppCtrl() { }]);
});
I created to Plunk to demonstrate what I mean. There's not much there: the ng-app defined, references to the angular files and a couple of titles to delineate the insert point. Nothing is shown between.
What is the simplest way to use ng-include in angular.js?
Place ng-app on your body section.
Include angular-route.js (eg. <script src="http://code.angularjs.org/1.2.0/angular-route.js"></script>) and add this dependency to your app initialization (var app = angular.module('app',['ngRoute'])
Don't put your script.js code inside (function(){}). (If you want to do this, call this function (function(){})();)
Your code with changes: http://plnkr.co/edit/k1dFPeb9E2B2pjTthi1K?p=preview
This is a script of mine:
HTML:
<div id="superhero-nav-container">
<ul id="superhero-nav">
<li><a ng-click='template = templates[0]'>Biography & Stats</a></li>
<li><a ng-click='template = templates[1]'>History</a></li>
<li><a ng-click='template = templates[2]'>Powers</a></li>
<li><a ng-click='template = templates[3]'>Enemies</a></li>
</ul>
</div>
<div class="superhero-templates" ng-include src='template.url'></div>
JS in the controller:
$scope.templates = [
{ url: '/views/superheroes/biography.html' },
{ url: '/views/superheroes/history.html' },
{ url: '/views/superheroes/powers.html' },
{ url: '/views/superheroes/enemies.html' }
];
$scope.template = $scope.templates[0];
I have something like menu that changes the html in the bottom div. Hope that helps.
EDIT (for the comment below):
Your mistakes were:
Put your ng-app attribute in the html tag of the
document not in the head
Include angular-resource.js (eg. <script src="https://code.angularjs.org/1.2.15/angular-resource.js"></script>) and add this dependency to your app initialization:
angular.module('app', ['ngResource']) ...
Don't put your script.js code inside (function(){}). If you want to do this, call this
function (function(){})();
Here is your working code: Plunker

Require directive on template

I am using RequireJS in my Angular app. I would like to require my pill where it is actualy used.
pill.js
define([], function() {
angular.module('app').directive('pill', function() {
return function(a,b,c) {
b.html("A pill");
};
});
});
incl.html
<div load-script="require(['pill']);"></div>
<div pill>test</div>
main.html
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js"></script>
<script src="http://requirejs.org/docs/release/2.1.10/comments/require.js"></script>
</head>
<body>
<script>
var app = angular.module("app", [])
app.directive('loadScript', function() {
return {
link: function(scope, element, attrs) {
(new Function(attrs.loadScript))();
}
};
}
);
</script>
<div ng-include="'incl.html'"></div>
</body>
</html>
This short example should declare a pill directive that just transform text from test to A pill inside incl.html file. However, it doesn't work. I guess it is because the pill directive is registered after incl.html is compiled.
I want avoid declaring directives somwhere globaly for example inside main.html because it is not used there. Is this requirement achievable in elegant way?
The best way to load directive on demand is to create it using $compileProvider which you will need to cache during your app.config phase. Also, instead of using ng-include, I would suggest you load the directive you need when partial view that uses it loads.
To do that, it is actually quite complicated. I created following library that should help get you started:
http://marcoslin.github.io/angularAMD/
angularAMD would make it easier for your create a independent file that allow you to configure RequireJS dependency to load the directive only on the partials that needs it.

angular load template from url and compile inside div

As I'm new to Angular JS I was wondering how could I load an external template and compile it with some data into the targeted div.
For instance I have this template :
<script type="text/ng-template">
<img src="{{Thumb}}" />
<script>
The div that is supposed to contain the template :
<div data-ng-controller=" ... "></div>
The template is located somewhere in a folder /templates/test.php. Is there a build in way of doing the template loading like a directive would do and compile it against some data that would replace the key {{Thumb}} ( and many others of course ) ?
EDIT : What if I use $routes and load a template when I'm in the root of the website ? How could that be achieved ?
Using $templateRequest, you can load a template by it’s URL without having to embed it into your HTML page. If the template is already loaded, it will be taken from the cache.
app.controller('testCtrl', function($scope, $templateRequest, $sce, $compile){
// Make sure that no bad URLs are fetched. If you have a static string like in this
// example, you might as well omit the $sce call.
var templateUrl = $sce.getTrustedResourceUrl('nameOfTemplate.html');
$templateRequest(templateUrl).then(function(template) {
// template is the HTML template as a string
// Let's put it into an HTML element and parse any directives and expressions
// in the code. (Note: This is just an example, modifying the DOM from within
// a controller is considered bad style.)
$compile($("#my-element").html(template).contents())($scope);
}, function() {
// An error has occurred here
});
});
Be aware that this is the manual way to do it, and whereas in most cases the preferable way would be to define a directive that fetches the template using the templateUrl property.
in Angular there's 2 ways of using template (at least 2 ways that i know about):
the first using an inline template (in the same file) with this syntax:
<script type="text/ng-template">
<img ng-src="{{thumb}}">
</script>
the second one (what you want) is external template:
<img ng-src="{{thumb}}">
so what you need to do is to remove the script part from your template and then use the ng-include in the wanted div like this:
<div ng-include="'templates/test.php'"></div>
need to have double quotes and single quotes to work.
Hope this helps.
Let's say I have this index.html:
<!doctype html> <html lang="en" ng-app="myApp">
<body>
<script src="tpl/ng.menu.tpl" type="text/ng-template"></script>
<mainmenu></mainmenu>
<script src="lib/angular/angular.js"></script>
<script src="js/directives.js"></script>
</body>
</html>
And I have a template file "tpl/ng.menu.tpl" with only these 4 lines:
<ul class="menu">
<li>view1</li>
<li>view2</li>
</ul>
My directives mapping "js/directives.js":
angular.module('myApp',['myApp.directives']);
var myModule = angular.module('myApp.directives', []);
myModule.directive('mainmenu', function() {
return {
restrict:'E',
replace:true,
templateUrl:'tpl/ng.menu.tpl'
}
});

Categories

Resources