Sharing Top Content from the Angular-sphere.

[SOLVED] Can you change templateUrl on the fly?- Angular.js Recipes

  • Unlike the current angular supported method of using a function for template or templateUrl, you can use scope information to determine the template to load.
  • directive(‘boom’, [‘$http’, ‘$templateCache’, ‘$compile’, function ($http, $templateCache, $compile) { //create a cache of compiled templates so we only compile templates a single time.
  • var cache= {}; return { restrict: ‘E’, scope: { Template: ‘&template’ }, link: function (scope, element, attrs) { //since we are replacing the element, and we may need to do it again, we need //to keep a reference to the element that is currently in the DOM var currentElement = element; var attach = function (template) { if (cache[template]) { //use a cloneAttachFn so that the link function will clone the compiled elment instead of reusing it cache[template](scope, function (e) { //copy class and style e.attr(‘class’, element.attr(‘class’)); e.attr(‘style’, element.attr(‘style’)); //replace the element currently in the DOM currentElement.replaceWith(e); //set e as the element currently in the dom currentElement = e; }); } else { $http.get(‘/pathtotemplates/’ + template + ‘.
  • success(function (content) { cache[template] = $compile(content); attach(template); }).
  • If you want more here is a cool article

    This is a new feature in Angular versions 1.1.4+ I just found out if I use the current unstable (1.1.5) you can pass a function into the template url of a directive.

It is possible, but when your template to be loaded depends on some scope-data you can’t use the directive’s templateUrl property anymore and you will be obliged to use lower-level API, namely $http and $compile.

Roughly what you need to do (only possible in the linking function) is to retrieve template’s content using $http (don’t forget to involve $templateCache!) and then compile template’s content “manually”.

It might sound like it is a lot of work but in practice it is rather straightforward. I would suggest having a look at the ngInclude directive sources where this pattern is used.

Here is a skeleton of such a directive:

app.directive(‘boom’, function($http, $templateCache, $compile, $parse) {
return {
restrict: ‘E’,
link: function(scope , iElement, iAttrs) {
var boom = $parse(iAttrs.data)(scope);
$http.get(‘myTemplate’+boom, {cache: $templateCache}).success(function(tplContent){
iElement.replaceWith($compile(tplContent)(scope));
});
}
}
});

assuming that it would be used as <boom data=’name’></boom>. Working plunk here: http://plnkr.co/edit/TunwvhPPS6MdiJxpNBg8?p=preview

Please note that I’ve changed attributes evaluation from {{name}} to attributes parsing since probably a template should be determined only once, at the beginning.


@angular_recipe: Can you change templateUrl on the fly? #Angular #AngularJS

Is it possible to change templateUrl on the fly by passing values in the directive’s scope? I want to pass data to controller that will render the page based on the data that passed from the directive

something maybe that looks like that:

!) and then compile template’s content “manually”.

directive sources where this pattern is used.

Here is a skeleton of such a directive:

to attributes parsing since probably a template should be determined only once, at the beginning.

I’ve changed the answer from pkozlowski.opensource a little.

From:

var boom = $parse(iAttrs.data)(scope);

To:

var boom = scope.data.myData

That worked for me and it’s possible to use

in the directive.

I had similar problem

This is a followup answer that addresses a few issues with previous answers. Notably, it will only compile templates once (which is important if you have a lot of these on your page, and it will watch for changes to the template after it has been linked. It also copies class and style from the original element to the template (although not in the very elegant way angular does internally when you use “replace: true”. Unlike the current angular supported method of using a function for template or templateUrl, you can use scope information to determine the template to load.

.directive(‘boom’, [‘$http’, ‘$templateCache’, ‘$compile’, function ($http, $templateCache, $compile) { //create a cache of compiled templates so we only compile templates a single time. var cache= {}; return { restrict: ‘E’, scope: { Template: ‘&template’ }, link: function (scope, element, attrs) { //since we are replacing the element, and we may need to do it again, we need //to keep a reference to the element that is currently in the DOM var currentElement = element; var attach = function (template) { if (cache[template]) { //use a cloneAttachFn so that the link function will clone the compiled elment instead of reusing it cache[template](scope, function (e) { //copy class and style e.attr(‘class’, element.attr(‘class’)); e.attr(‘style’, element.attr(‘style’)); //replace the element currently in the DOM currentElement.replaceWith(e); //set e as the element currently in the dom currentElement = e; }); } else { $http.get(‘/pathtotemplates/’ + template + ‘.html’, { cache: $templateCache }).success(function (content) { cache[template] = $compile(content); attach(template); }).error(function (err) { //this is something specific to my implementation that could be customized if (template != ‘default’) { attach(‘default’); } //do some generic hard coded template }); } }; scope.$watch(“Template()”, function (v, o) { if (v != o) { attach(v); } }); scope.$on(‘$destroy’, function(){ currentElement.remove(); }); } }; } ])

, which we don’t use often.It can be a function which returns a url.That function has some arguments. If you want more here is a cool article

This is a new feature in Angular versions 1.1.4+ I just found out if I use the current unstable (1.1.5) you can pass a function into the template url of a directive. The second parameter of the function is the value of the attribute directive as shown below.

Here is a link to the unpublished docs showing the official change.

as the template url from

Html:

Directive:

.directive(‘subView’, [()-> restrict: ‘A’ # this requires at least angular 1.1.4 (currently unstable) templateUrl: (notsurewhatthisis, attr)-> “partials/#{attr.subView}.html” ])

Angular.js Recipes are structured in a Cookbook format featuring recipes that contain problem statements and solutions. A detailed explanation follows each problem statement of the recipe. This is usually contained within the solution; however, an optional discussion section can often contain other useful information helping to demonstrate how the solution works.

Angular.js is a JavaScript-based open-source front-end web application framework mainly maintained by Google and by a community of individuals and corporations to address many of the challenges encountered in developing single-page applications. The JavaScript components complement Apache Cordova, the framework used for developing cross-platform mobile apps. It aims to simplify both the development and the testing of such applications by providing a framework for client-side model–view–controller (MVC) and model–view–viewmodel (MVVM) architectures, along with components commonly used in rich Internet applications.

Lost? Begin by working through Angular’s Getting Started Guide to get yourself up-and-running.

[SOLVED] Can you change templateUrl on the fly?- Angular.js Recipes

Comments are closed, but trackbacks and pingbacks are open.