Scenario:-
I have html page rendering as angular template/view. Now there are big number of such template.
Now these templates has div in header part that is fixed through out the templates, now is there some-way that we can define one sub-template at one place and just insert that sub-template in all pages.
So that if there are any modification to be made, I will make in sub-template and that will be reflected in all the page.
Its like UserControls or Partials that we have in ASP.Net.
I am using AgularJS
Agreed that there are ui-routing for nested hosting but currently I am not looking for that.
Try
<div ng-include="path/to/template"></div>
you can create a seperate html file as template for header if it includes complex or considerable amount of elements. create a directive for this template and use it as an attribute/customTag or include it in your html using ng-include.
app.directive('header',function(){
return {
restrict: 'E', //'E': element /'A': attribute
templateUrl : 'templates/header.html'
}
});
use as attribute
<div header></div> // as Attribute
<header></header> // as element
if your header involves lot of functioning on it then you can also create a separate controller (which will act as a child controller) and add the controller to the above tags. such as
<header ng-controller="headerController"></header>
You probably want to use a directive template. This is a very simple directive with only the template information.
Eg:
<top-header></top-header>
module.directive('topHeader', function() {
return {
templateUrl: 'path',
// append
replace: true,
// attribute restriction
restrict: 'E'
}
});
Related
I have a little directive and I have troubles to make it working.
here is my directive :
angular
.module('thermofluor')
.directive('myCustomer', function() {
return {
restrict: 'E',
template: 'table_plate.html'
};
});
The template is just a paragraph with "Test" inside.
In my main HTML in call the directive with this :
<my-customer></my-customer>
but nothing appear on the screen, and in the html the directive is not replace with the directives output html
The template have the same name and is in the same folder.
What am I doing wrong ?
Thanks.
It should be templateUrl
return {
restrict: 'E',
templateUrl: 'table_plate.html'
};
If you only need the template to show, you can use ng-include instead directive:
<ng-include
src="string"
[onload="string"]
[autoscroll="string"]>
...
</ng-include>
There is also the version for any element available:
<ANY
ng-include="string"
[onload="string"]
[autoscroll="string"]>
...
</ANY>
For even more info glance on https://docs.angularjs.org/api/ng/directive/ngInclude
Under either src or ng-include put the reference to the template you wish to load (depending on what version you use). For only 1 restrict it's kinda overkill to use a directive, rest you get from this approach as well.
NOTE: in above definitions, attributes in brackets are not needed for your example.
In angularjs, I have already made view templates consisting of multiple controllers. Now while routing can we specify multiple controllers to one template or there should be only one controller for a template?
If you do not understand this question please specify in comment.
Actually, the answer is no. You can't use multiple controller in router state, however you can add multiple controller in template HTML.
Alternate solution is using dynamic template in a directive. If you use the dynamic template, then for each router state you can use multiple controller in different different HTML template.
app.directive('View', function () {
return {
restrict: 'E',
scope: {
templateUrl: "=",
},
replace: true,
template: "<div ng-include = 'templateUrl'></div>",
};
})
Then in directive you can do that by just passing different template url.
And in your template you can use different different controller.
In html you can use directive as follows:
<view templateUrl = "templateUrl0.html"> <view>
<view templateUrl = "templateUrl1.html"> <view>
Finally, in the templateUrl0.html and templateUrl1.html, you can add Controller0 Controller1.
I am trying to write a simple CMS system where the content of each page is stored in a database. When the user tries to access
/pages/abc.html
through angular routing and controller to retrieve the content of that page from the database and generate abc.html on the fly. I found one way is to add a function to templateUrl to return the page:
.when('/content/pages/:name*', {
templateUrl: function(parameters) {
return '/pages/' + parameters.name + '.html';
},
controller: 'ContentCtrl',
controllerAs: 'content'
})
However the issue is I need to have abc.html already exist and then in the controller to compile the DOM content and attach it. What I am trying to do is not to have the abc.html already exist, but generated on the fly. This way I can allow my user to add xyz content and when they try to access xyz.html it will be there, without having to create xyz.html template html upfront. Is there any method I can use to achieve this.
Is there any reason you need to generate the parameters.name html file? I would think you could define the template as then pass the html into the controller. If there is a lot of repeated logic, you could make a content component or directive.
What I did for this is write a custom directive. I pass the directive an array that contain objects that correspond to ui elements. The objects are defined in JS and all have a .html() function I wrote that generates some html based on the objects properties. Then to store/restore the structure you can just JSON.stringify the object to insert it in the DB and JSON.parse to get the object back... Only tricky part is you need to store the data type as a property of the object so you can pick the right type.
The directive itself just calls the html() function on each object and concatenates the output then sets the innerHTML of the element.
I realized I could just use the template property to insert any html I want.
.when('/content/pages/:name*', {
template: function(parameters) {
return 'hello' + parameters.name;
},
controller: 'ContentCtrl',
controllerAs: 'content'
})
What you can do it pass template name as a parameter to the controller:
.when('/content/pages/:name*', {
templateUrl: function(parameters) {
return '/pages/:templateName';
},
controller: 'ContentCtrl',
controllerAs: 'content'
})
And in the controller, create the required HTML (if not existing) and then in template include the HTML using ng-include:
<div ng-include="template.url" ng-if="template.url"></div>
In my MEAN app, I use jade as my template engine. My problem is, when I call an angular directive, jade code is not working but html code is working. My code is given below:
index.jade
div(ng-repeat="num in addDir")
admin-collection
directive.js
var formDir = angular.module("formDirective", []);
formDir.directive('adminCollection', function() {
return {
restrict: 'E',
transclude: true,
// call jade template url
templateUrl: '../_template/_formTemplate/_adminCollection.jade'
};
});
_adminCollection.jade
h1 from _adminCollection templateUrl
If I use jade format code in _adminCollection.jade, it just show a plain text, not text inside h1 tag
But following code is working:
directive.js
var formDir = angular.module("formDirective", []);
formDir.directive('adminCollection', function() {
return {
restrict: 'E',
transclude: true,
// call jade template url
templateUrl: '../_template/_formTemplate/_adminCollection.html'
};
});
_adminCollection.html code::
<h1> from _adminCollection templateUrl </h1>
How can I solve this problem?
Jade is a template engine. Browser has only built-in html parser, so it does not understand what jade code means and treats it as plaintext.
To make it work you need to convert it to html. You can use some task manager to do it. Two most popular task managers for node.js are gulp and grunt. Each of them has a working jade plugin which you can use right away.
Jade is something like less - it must be convert to another format, because browser can't understand that. When you use less, you have to transform it to css. And if you use jade - to html.
If you use grunt, you should look on it: https://github.com/gruntjs/grunt-contrib-jade
Otherwise you can check if your IDE can transform jade to html. For example PhpStorm can do this in automatic way.
Then in your directives you should specify path to html template, no jade.
You can use following directory structure:
app/
src/
js/
less/
jade/
dist/
templates/ <-- here you can put your htmls
styles/ <-- and here put css
js/ <-- if you want, you can put this minimalized app.js
that will contain all of your project,
see grunt-contrib-uglify for more info
EDIT: here is really great article about grunt: http://anthonydel.com/my-personal-gruntfile-for-front-end-experiments/ There is much more then you need, but maybe it will help you
.... Or you can to use webpack to do the work.
then you can load the template like this:
angular.module('app').component('myComponent', {
bindings: {},
template: require('./mytemplate.jade')()
});
You can to note that I'm invoking the returned function.
Another option is to keep the HTML templates in your DOM, but hidden:
div(ng-non-bindable, style="display: none")
#adminCollectionTemplate
div(ng-repeat="num in addDir")
admin-collection
#anotherTemplate
//- Alternatively, pull in the template from another file
include ./_formTemplate/_adminCollection.jade
and then use jQuery to fetch the HTML out of the DOM, and give it to angular:
formDir.directive('adminCollection', function() {
return {
restrict: 'E',
transclude: true,
// fetch template from DOM
template: $('#adminCollectionTemplate').html()
};
});
This will just work, without any Ajax or any task runners. But it will clutter up the DOM with templates that could otherwise be hidden away in the JS. And it is an extra step to place every new template into that div.
ng-non-bindable is needed to tell Angular to leave the template elements alone (don't manipulate them or bind to them), until their clones are actually used by the directive.
I have a directive that lets me insert a chat component. It loads a template as required.
mod.directive('chat', function () {
return {
replace: true,
templateUrl: '/tmpl/chat/chat',
}
})
But the problem is that the template needs additional includes:
.chat
.chatHeader(ng-include="'chatHeader'")
.chatLog(ng-include="'chatLog'")
Partials:
script( type="text/ng-template", id='chatLog')
.chatMsg(ng-include="'chatMsg'", ng-repeat='chatMsg in chatLog')
script( type="text/ng-template", id='chatHeader')
h3 Chat
How do I load the includes? I used to put the partials in the same file as base chat template but if I use replace: true that's no longer allowed.
What's the standard angular way to load included partials?
Using ng-include as you are is perfectly valid. The issue you are facing is likely because your template partial does not have exactly 1 root element. Here is a plunk with a working version of what you are describing: http://plnkr.co/wy1a3T1UdKOlBQXr9o22