The CreatorCon Call for Content is officially open! Get started here.

[Service Portal] How to use one ng-template in multiple widgets ?

Community Alums
Not applicable

Hi guys,

I'm trying to use the same ng-template in multiple widgets. Here is my method with no Angular ng-template dependency : 

sp_ng_template record (with the Widget field empty)

find_real_file.png

Widget

<div>

  <ul>
    <li ng-repeat="contact in c.data.myContactList" ng-include="'csaTemplateExample.html'">
    </li>
  </ul>

</div>

 

The ng-include doesn't work if I don't create a dependency between the template and a widget. If I put the Widget name, my ng-include is displayed but therefore, my template is linked to that Widget.

So, how can you use the template with many widgets ?

 

Thanks in advance

Christophe

1 ACCEPTED SOLUTION

Dan Conroy
ServiceNow Employee
ServiceNow Employee

It is a one-to-one relationship, but there are some options:

  • Include the template in the header or footer widget and then it will be available to other widgets as it is cached. Downside is you might be loading it when you don't need it.
  • Use the $templateCache service and cache your own template. You can create a new service, and store the template there, and publish it to the cache.

View solution in original post

14 REPLIES 14

janlarsen
Tera Contributor

In order to reduce widget cloning I have been exploring how to make widgets more configurable from the instance (options) level. The goal is to fetch pre-made code snippets from instance options.

At this point the bottle points at:
1) ng-templates
2) Angular Providers

According to my tests both methods suffer from the fact, that they have to be related to the relevant widget prior to execution. This is less than optimal - and not very flexible IMO.

Then this post turns up reveiling, that ng-templates - unlike providers - may be collected behind the scenes in $templateCache and referenced from there.

But how do you do that exactly, @Dan Conroy (and others, please)?

The addition below to my widget client script doesn't work, even though `c.widget.ngTemplates` replicates precisely the content from `widget.ngTemplates`, when both ng-templates have been related to the widget.

c.widget.ngTemplates = {"task-category4": "<span>{{item.number}} - {{item.short_description}} - {{item.category}}</span>", "task-category2": "<span>2: et-eller-andet</span>"};
    
$templateCache.put('tngTemplates', c.widget.ngTemplates);
    
$templateCache.get('tngTemplates');




This page on $templateCache from Angularjs.org provides som clues, but how do you translate those into a SN-widget syntax?

James Freund
Tera Contributor

@Dan Conroy @christophes. 

Just discovered a new solution. I have come back to this issue quite a few times and have used $templateCache, but it is not a good permanent solution.

 

After looking at numerous OOB directives that get their template by an angular service named getTemplateUrl. I have found that getTemplateUrl is actually pulling form the UI Macros table.

 

So you can actually move your templates to the macros table, removing any useless jelly script and xml along the way. Then just copy the name of that macro from the API Name field and use that for your templateUrl in your directive.

 

For example I created dmDocTemplate in my scoped app, the API Name of that Macro is now set to:
x_saw_doc_dmDocTemplate.

 

My example macro was just basic html with the default jelly and xml removed:

<div class="dm-doc">
	<span>Simple Template through macro example</span>
	<span ng-bind="something"></span>
</div>

 

Then I can access that template from my directive using this:

function dmDoc (getTemplateUrl) {
	return {
		restrict: 'E',
		replace: true,
		scope: {
			something: '='
		},
		templateUrl: getTemplateUrl('x_saw_doc_dmDocTemplate'),
		link: function(scope, element, attrs) {
		
		}
	}
}

 

This directive can now pull that template without needing the template to be associated to a single widget!

Community Alums
Not applicable

Thanks James, I'll test it !

This is great @James Freund . But I just found one issue with this approach. It seems that UI macros are being cached and unless the user clears the browser cache he will still see the original version of the template defined within UI macro. Any idea how to enforce retrieval of the latest version of template?

I noticed this issue as well. What I have done in the past is create new macro's each time until I get to whatever the final template should be. Then I go back and delete the other macros.

The caching is really frustrating, but pointing to a new template name isn't too bad if you're just adding V1, V2, V3, etc to the end of each macro name.