Parse content within angular directive template before rendering - javascript

Since there is no ng-url directive to use with an #import statement the way ng-src works, I am trying to create a directive for this purpose, the code is like this
.directive('importCss',
function()
{
return {
restrict: 'E',
replace: true,
scope: { loadCss : '=' },
template:'<style>' +
' #import url("{{loadCss}}")' +
'</style>',
};
}
);
The idea basically is to create HTML like this:
<style>
#import url("http://url_to_css_in_parameter")
</style>
Probably this is something very basic, but what is happening is that in my controller I have some init code that runs before asigning values to the scope var assigned to the loadCss parameter. The value is initialized to '' at the start of the controller code. The problem is that a request is made to the server requesting "http://serverAddr/{{loadCss}}" before it does the actual correct request with the values applied to the template.
Here is the callstack for the wrong request (screenshot):
Any idea while the template is being rendered before compiling and how to solve it? Thanks very much.

Related

why templateCache not working in angular js?

I am trying to use $templateCache.But when I console using $templateCache.get() it give me undefined ..why ?
http://plnkr.co/edit/MAXQmzTVR8fpsw645rct?p=preview
<script>
angular.module('app',[ ]).directive('h',function($templateCache){
console.log($templateCache.get('about.html'))
var element=angular.element('<input type="text" ng-model="message"><div>{{message}}</div>');
return { restrict:'E',
scope:{},
templateUrl:'a.html',replace:true,
transclude:true,
compile:function(tElement){
tElement.append(element);
return function(s,e,a){
s.$watch('message',function(val){
// console.log('------'+val)
})
}
}
}
})
</script>
**console.log($templateCache.get('about.html'))** give me undefined why ?
Because currently you are running that statement while registering that directive. That time $templateCache don't have the templates in it.
You need to put that line inside directive compile function then only you will get data in it.
See this question I think this should help you
Angular Tabs render templates with caching in "ng-include src"
template is is loaded in the template cache for quick retrieval.
You can load templates by $templateCache service directly.
angular.module('app', []).run(function($templateCache) {
$templateCache.put('a.html');
});
To retrieve simply use it in your HTML
<div ng-include=" 'a.html' "></div>
or
$templateCache.get('a.html')

Unit Testing: Directive with Dynamic Template

I am running across an issue when trying to use an unusual method to grab templates for my page-content. I have abstracted it but suffice to say that the code works fine but the testing is throwing up some issues. I have listed my directive below:
Directive:
return {
restrict: 'A',
scope: {
page: '=pageCode',
},
link: function (scope, element) {
$http.get('templates/' + scope.page + '.html', {cache: $templateCache})
.success(function(html) {
element.replaceWith($compile(html)(scope));
});
}
};
Basically, when this directive is called with the page-code attribute, it grabs it and pulls in a specific partial for that page content. I have tried mocking out a $scope to contain the code but that wasn't working so I am hardcoding the data-page-code="404" for now. The test is as follows:
Directive Test:
it('should compile and pass through the scope', function() {
mockDirectiveHtml= '<div data-page-content data-page-code="404"></div>';
mockTemplateHtml= '<h1>Hi</h1>';
$httpBackend.expectGET('templates/404.html').respond(mockTemplateHtml);
pageContentHtml= $compile(mockDirectiveHtml)($scope);
$scope.$digest();
$httpBackend.flush();
expect(pageContentHtml.html()).toEqual('<h1>Hi</h1>');
});
However when this runs, the console is telling me it is trying to hit GET('templates/undefined.html'). Now I am unsure if I have things in the right order, or if that is even the solution but has anyone came across something like this in the past? I assume the directive is running before the attributes are passed to it so when it comes to grab templates/' + 'scope.code' that value is undefined.

AngularJS directive with script

Basically, I have my directive defined sample.js as:
app.directive('myDirective', function() {
return {
restrict: 'E',
scope: {
info: '='
},
templateUrl: 'link-to-sample.html'
};
});
And in my sample.html I got (for example):
<script>
$(div).css('height', {{info}}+'px') //THIS DOESN'T WORK
</script>
<div></div>
In my, say, index.html I would like to pass a numerical value, through the info='' tag and use it in the script, running in the sample.html file.
<my-directive info='100'></my-directive>
But using just {{info}} in <script></script> tags seems not to work.
Would be grateful, if you, guys, help me with this.
P.S. I know, that I could write a code inside directive, use compile, or template:, but I would really like to keep in the separate .html file.
Embedding script tags in template files to deal with DOM in directives is strongly discouraged. It does not play well with the Angular way of DOM updates, and it does not have access to scope and the surrounding directive. Also, it will break under CSP where inline scripts are disallowed.
The recommended way would be to use the link function and remove the script tag in templates.
app.directive('myDirective', function() {
return {
restrict: 'E',
scope: {
info: '='
},
templateUrl: 'link-to-sample.html',
link: function (element, $scope, attrs) {
element.find('div').css('height', $scope.info + 'px');
},
};
});
You can still keep the separate sample.html for your template HTML. You just don't put logic in it. This is better separation of concerns in my opinion.
<div></div>

Angular code stops working when it's moved to a template file

I'm new to Angular, so the documentation is a bit of a bear. When I created the following code, and it worked, I thought I was in a good place.
<div ng-controller="postListController">
{{someDataStuff}} <!-- this always works -->
<div ng-repeat="post in data">
<b>{{post.title}}</b> <!-- This sometimes works -->
</div>
</div>
...and this Javascript in Angular (a snippet, really)
var listController = app.controller('postListController', function postListController($scope) {
$scope.someDataStuff = 'hey there.';
$scope.data = new Object(null);
$.get('get.php',function(data) {
$scope.data = JSON.parse(data);
console.log($scope.data);
});
});
someDataStuff printed out, and Angular looped happily through the post.titles. Then I tried moving this stuff, verbatim, to a template file and loading it appropriately...
app.directive('ngPostList', function() {
return{
restrict: 'E',
templateUrl: 'postlist.html'
}
});
This part... only sorta worked. While I was still getting data (returned it in console.log), and I was still getting someDataStuff to come back, it was no actually looping through the data.
Is there something in app.directive I'm missing to make it pass data on to the template I'm now using?
Your template should also take the controller, otherwise it is outside the scope and you are one level further down and you would have to call $parent.post.title etc... to reach the proper parent scope with the data.
try:
app.directive('ngPostList', function() {
return{
restrict: 'E',
Controller: 'postListController',
templateUrl: 'postlist.html'
}
});
Overall, pick up one of the Chrome extensions to debug Angular, like ng-inspector, so you can see what scope has what data and it makes your life a lot easier to debug this kind of things.
Angular issues are 95% of the time issues with scope not being what your think it is.

ng-bind-html not processing INPUT

I would like to bind html with the content of $scope.value = "<input type=text name=a>"
Nothing is inserted inf the DOM, but if $scope.value = "Hello <i>Guys</i>" everything is fine.
Is there a limitation/bug with ng-bind-html? Is there a workaround?
I am using 1.2.4 version of angularJS
Thanks for your help, this is a big issue for my development
Christophe
Can't you use a Directive instead of that? This way I think you get rid of your problem
http://docs.angularjs.org/guide/directive
https://egghead.io/search?q=directive
A small example:
angular.module('myApp').directive('myDirective', function(){
return {
restrict: 'E',
replace: true,
// you can set 'transclude: true' instead of the following line to create a new scope but inheriting from the parent
scope: false, // this will make the directive have the same scope as the parent
templateUrl: 'my-html-template.html'// you can load the template like this
// You can also use 'template' and include the html code here
}
});

Categories

Resources