ng-bind-html not processing INPUT - javascript

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
}
});

Related

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.

Parse content within angular directive template before rendering

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.

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.

angularjs regex filter syntax highlighter

please take a look at this plunker: http://plnkr.co/edit/OIFu07GS0ZJQOdmpDnXB?p=preview
i am trying to create a syntax highlighter with angular. I have the filter working 80%. The regex is correct but the .replace() it "writes" the html as text on the pre and not rendering it as html.
take a look and you will understand what I am trying to do.
I know there are codemirror and ace directives but they are just too big for what I need.
anyone know how to fix it?
the correct output should be something like this:
<pre>
<span class="string">1</span>
<span class="string">2</span>
<span class="string">3</span>
#This is a mysql syntax highlighter
-- This is a comment/*
And this is a multi line comment
SELECT things FROM table;*/
</pre>
currently everything between pre is rendered as text.
any ideas?
thanx
I don't think you can do this with a filter, try a directive.
Below is an example, fairly straightforward. I first changed the filter to a service (though you can use the filter similarly with $filter if you want but I don't see why). Then I use $interpolate to create an interpolation function, described here:
Compiles a string with markup into an interpolation function. This service is used by the HTML $compile service for data binding. See $interpolateProvider for configuring the interpolation markup.
You can see in the example that the strings '1', '2' and '3' are highlighted because I added style="color:red", and they have the class as well.
Edit: edited solution with usage of ngModelController to make changes to the textarea appear in the element below with angular's data binding. Note the change to the snippet element: <snippet ng-model="txt">
var app = angular.module('plunker', ['syntax']);
app.controller('MainCtrl', function($scope) {
$scope.txt = "1 2 3 \n #This is a mysql syntax highlighter\n-- This is a comment/*\nAnd this is a multi line comment\nSELECT things FROM table;*/\nSELECT \nag.name AS agent, `d.date`, d.first_payment_date, d.account_number, ";
});
angular.module('syntax', [])
.service('formatter', function () {
return function (input) {
if (input) {
return input.replace(/(\d+)/g, "<span class=\"string\" style=\"color:red\">$1</span>");
}
}
})
.directive('snippet', function($timeout, $interpolate, formatter) {
return {
restrict: 'E',
template:'<pre><code></code></pre>',
replace:true,
require: '?ngModel',
link:function(scope, elm, attrs, ngModel){
ngModel.$render = function(){
var tmp = $interpolate(scope.txt)(scope);
elm.find('code').html(formatter(tmp));
}
}
};
});
http://plnkr.co/edit/783ML4Y2qH8oMLarf0kg?p=preview

Categories

Resources