injecting html content in empty template - angularjs

I retrieve the code of an HTML page from a server thanks to a rest service and I want integrate the html code into an empty template
.controller('TestController', ['$scope' ,'$rootScope' , '$sce' , function ($scope ,$rootScope,$sce) {
var restHtml =$rootScope.test; //contains <div>Test</div>
$scope.showHtml= $sce.trustAsHtml(restHtml );
}]);
The template
<div ng-bind-html="showHtml"></div> <!-- didn't work and i want a solution without integrate my html code into a existing div -->
Thank you

Ideally DOM manipulations should not happen in the controller, directives should be used for them.
To answer your question, you could compile the html into your tag. Get the html, find the element you want to insert the html in and use compile to do it. A good example of compile.

Related

HTML and JAVASCRIPT Editor in Angularjs

I have an angularjs 1.5.8 application created using Jhipster.
For my website I want to make a HTML and JAVASCRIPT editor. Need to allow user to write HTML Code but JAVASCRIPT also.
Using this library I know I can achieve the follow.
https://github.com/incuna/angular-bind-html-compile
1: Bind HTML Code.
2: Bind Angular code if present in HTML
Eg: <h1>{{$scope.test}}</h1>
Would render correct value in the scope.
But what about something like this in the html
<script>
console.log($scope);
</script>
I get a $scope not defined error, somehow the $scope value is not available in the script tag.
If anyone curious that why I need to do this because we want to provide users of the application to create there own Angularjs Forms.
I solved using ng-include, here is the example source.
I wanted to do two things.
1: Make ng-include work from a scope variable which will contain html and javascript.
2: In the included string if I have a script tag I wanted it to render correct in the ng-include.
To achieve the #1 I did the following.
Used $templateCache service.
Sample code.
$templateCache.put('template-form', vm.html + vm.script);
For point #2
I made sure the script tag is structured in the following way.
<script>
(function() {
'use strict';
angular.module('myApp').controllerProvider.register('AppTemplateController',AppTemplateController);
AppTemplateController.$inject = ['$scope'];
function AppTemplateController($scope){
// WRITE YOUR CODE IN THIS CONTROLLER
// YOU CAN WRITE YOUR VARIABLES/FUNCTIONS HERE.
// MAKE SURE TO CALL THE method "vm.submitForm", to submit your form and pass the form object.
};
})();
</script>
This way you can inject a controller.
My requirement was very very specific to my projecct, I am not sure if others who did not face this issue even would understand what I am talking about. But for those who do face it, I hope you it helpful

Angular bind HTML inside controller?

I currently have a data feed in my Angular setup which returns certain data as HTML. For example, it returns:
"It’s".
In the template, I can use ng-bind-html so that it displays as "It's", but how do I do this within the controller? I need to do this as I am setting the page title dynamically, but it is displaying the HTML characters above, rather than formatting it correctly.
E.g. using:
$scope.name = data.word (but formats HTML?)
inject $sce and use the following code
$scope.name = $sce.trustAsHtml(data.word;
I solved this. I simply placed the ng-bind-html onto the <title> tag. So:
<title ng-bind-html="seo.pageTitle"></title>

Directive's templateUrl referencing div instead of entire HTML

I've got a list of pop-ups/dialogs (enclosed in divs) that I want to place in a single HTML file and from there reference in different directives representing those pop-ups. As far as I know, AngularJS directive's templateUrl normally reference an HTML file. Is it possible to reference a single div within HTML for templateUrl? If it is, how to do it?
If your template fragments are small, you can reference them from within your JS by using the template: parameter instead of templateUrl:. However, in my projects, I reference all the template partials by templateUrl and use a grunt task to preload all the individual HTML files into one Javascript file that is then loaded by Angular into the template cache. You can read more about it here.
You can do the following:
Add the div's as a <script> and add the attributes type="text/ng-template" and id="", then when you set the templateUrl:, you pass the id from the script element.
Example:
HTML:
<script type="text/ng-template" id="template/awesomeDiv.html">
<div>
(...)
</div>
</script>
Directive:
templateUrl: 'template/awesomeDiv.html'
NOTE:
In order to use this, you need to have nested directives, so the parent directive includes your HTML with all divs, and the children uses the ng-template'd divs

AngularJS factory placement

i have this lightbox that pops up from time to time. There are 3 ways to close it. Close button, clicking the overlay that's outside it and another way. For the close action i decided to do a factory that looks like this:
app.factory('close',function(){
return {
close: function(){
$('.mySelector').fadeOut();
}
}
});
One of my HTML elements that i want to have close the lightbox would be something like this:
close lightbox
The question i am faced with is this: Should i inject the factory in a directive (seeing as it manipulates the DOM) or in a controller? - the controller is there either way since i need it for other stuff. The advantage of the first is that my markup would only have a controller attached to the top element of the lightbox and be done with it. The directive on the other hand will have to be attached to each element individually + there's the directive code itself (little of it may be).
This translates to:
added code for directive +
<top-element-of-lightbox ng-controller="myController"> <!-- controller does NOT have factory injected -->
<a href="" ng-click="close" **my-directive**>close lightbox1</a> <!--directive attached to element -->
<a href="" ng-click="close" **my-directive**>close lightbox2</a> <!--directive attached to element -->
...
</top-element-of-lightbox>
Versus:
0(zero) directive code +
<top-element-of-lightbox ng-controller="myController"> <!-- controller HAS factory injected -->
close lightbox1 <!-- no directive attachment -->
close lightbox2 <!-- no directive attachment -->
...
</top-element-of-lightbox>
Lastly, i am new to Angular so i would appreciate if you justify your response and also please tell me if i am going about this whole thing the right way and if there are areas where i could improve or an other approach would be better.
Do not manipulate your DOM in controller or services(service,
factory). You must do that in directive
Instead of using jQuery selector you can directly get hold of element and manipulate it inside directive
Using angular animations instead of relying on jQuery
Most importantly all your queries and above issue you face is solved in this awesome video which just explains creating a directive to hide stuff with animations.
https://egghead.io/lessons/angularjs-animating-the-angular-way
Cheers!!!!

Best way to modify html before binding to it in AngularJS directive

I'm writing an AngularJS app that gets a list of posts from a server, and then uses an ngRepeat and a custom post directive to output all the posts.
Part of the post object is a blob of html, which I currently add to the directive by first doing an $sce.trustAsHtml(blob), and then using the ng-bind-html directive and passing the trusted html blob to it. It works fine, but now I want to modify the html before adding it to the output. For instance, I want to find all link tags and add a target="_blank" to it. I also want to remove any content editable attributes from any element. etc.
What is the best way of doing this? I was thinking of just loading it up in a document fragment and then recursively iterating through all of the children doing what I need to do. But I assume there is a better AngularJS way to do this?
EDIT:
here is a codepen with an example of what I have:
http://codepen.io/niltz/pen/neqlC?editors=101
You can create a filter and pipe (|) your content through it. Something like:
<p ng-bind="myblob | myCleanupFilter">
Your myCleanupFilter would look something like this (not tested):
angular.module('myApp').filter('myCleanupFilter', function () {
return function cleanup (content) {
content.replace('......') // write your cleanup logic here...
};
});
If you want to add attributes that are themselves directives, then the best place to add them is in the compile function in a custom directive.
If they are just plain old attributes, then there's nothing wrong with hooking into DOM ready in your run block, and adding your attributes with jquery.
var app = app.module('app',[]);
app.run(function ($rootScope){
$(document).ready(function()
$rootScope.$apply(function(){
$('a').attr('title','cool');
});
})
});
If you want add the attributes after the compile phase but before the linking phase in the angular life cycle then a good place to do it is in the controller function for a directive that's placed on the body element.
<body ng-controller="bodyCtrl">
</body>
app.controller('bodyCtrl', function($element){
$('a', $element).attr('title','cool');
});
During the compile phase angular will walk the DOM tree, matching elements to directives, and transforming the HTML along the way. During the link phase, directives will typically set up watch handlers to update the view when the model changes. By placing a directive on the body element, it ensures that all directives have been compiled, but the linking phase hasn't started yet.

Resources