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
Related
$stateProvider.state('abc', {
url: '/:id',
modal: true,
template: '<abc></abc>'
})
can I have custom html tag in template property?, e.g. 'abc', I was looking at someone else code but I don't understand how this works, I do have abc.html processed by gulp templatecache stuff. and it is loaded in a modal dialog correctly.
the file is at 'src/app/components/abc/abc.html', how come the template 'abc' knows which html to load? I suppose there must be a definition for 'abc' directive somewhere? but I can't find it.
I finally figured how it works, turns out the custom html tag is defined by a 'component' and there is some naming convention making this work.
http://blog.grossman.io/angular-1-component-based-architecture-2/
https://docs.angularjs.org/guide/component-router
Can I have custom html tag in template property
Yes, of course. Templates can use custom directives no matter how they are defined.
There should be an 'abc' directive somewhere in your module code or one of its dependencies.
See this SO question to be able to list the registered directives of your module and submodules in the console.
Yes, you can use custom html. UI Router provides you two choices, either you give the template or the templateUrl, which for the first one you have to write your html in a string literal, and latter you can set a html file location.
using template with string literal:
$stateProvider.state('abc', {
url: '/:id',
modal: true,
template: '<abc></abc>' // this is correct!
})
using templateUrl with html files.
$stateProvider.state('abc', {
url: '/:id',
modal: true,
templateUrl: '/path/to/abc.html' // if you have a file named `abc.html` in directory `path/to`, the template will be loaded
})
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'
}
});
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 am new to AngularJs and struck with an issue. I have "index.html" where I need to have the main section loaded via the <div data-ng-view=""></div>. Now, the data inside the view will be populated by the controller using the below code
.when('/',
{
controller:'controllers.IndexCtrl',
templateUrl:'/partials/index-partial.html'
})
Inside the index-partial.html file I have used the custom directive linke below:
<custom-carousel/>
The code for the carousel is below:
myApp.directive('customCarousel', function() {
return {
restrict: 'E',
replace:'true',
templateUrl: "/partials/carousel.html",
link: function(scope, element, attrs) {
$('.my-list').click(function(){
$('.my-list').removeClass('active');
$(this).addClass('active');
});
}
};
});
The issue with the above approach is that the jquery code inside the directive gets called twice and hence the toggling of the selected li does not work.
I have below questions:
Is the jquery function inside the directive called twice because its called from the partial and once again during the ng-view?
Whats the reccommended way of handling this scenarios?
Whats the best approach to fix this issue. If I remove the templateUrl from the controller and directly use the custom-carousel inside the html, this works perfectly but I want to load the directive using the ng-view and not directly in the index.html file.
Please let me know the best approach to solve this issue.
I am using the Angular UI bootstrap module for opening a dialog.
There is a option for mentioning the path of template like
$scope.opts = {
backdrop: true,
keyboard: true,
backdropClick: true,
template: '<p>Template</p>',
controller: 'TestDialogController'
}
my app is in site/app then js , partials
I am not able to find how it finds templates
The Angular UI bootstrap dialog takes either a template inline,
template: '<p>This is a inline template</p>';
or the template url can be specified as both a relative and absolute path.
templateUrl: '/relative/path/dialog.html';
Try to open a browser tab pointing to your template first, and when you successfully have derived the path you can try to add it to your templateUrl.
You can read more about correct usage of the directive here.
There's a use of <script> as a directive which would allow you to make a hybrid approach.
Angular docs mention that if you use a declaration in your html like:
<script type="text/ng-template" id="/tpl.html">
Content of the template.
</script>
Then you can use it as a reference in a directive such as ngInclude or ngView, and even a service like $route. You can see this working in this fiddle.