Skip to content

Commit 555ddec

Browse files
committed
feat(Interpolation): Handle custom symbols
* Add a postProcessTemplate() function to the gridUtil service that swaps out interpolation symbols if they're different from the default ones. * Change getTemplate() to use this function when returning templates * Add tests to the gridUtil spec for getTemplate() with custom interpolation symbols Fixes #1576
1 parent a3f3f7e commit 555ddec

File tree

3 files changed

+179
-10
lines changed

3 files changed

+179
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
@ngdoc overview
2+
@name Tutorial: 313 Custom Interpolation Symbols
3+
@description
4+
5+
Combining AngularJS with other frameworks/tools sometimes requires changing the normal interpolation symbols (`{{` and `}}`) to something else, like `[[` or `%`.
6+
<br>
7+
<br>
8+
UI Grid will automatically detect the change and transform any default symbols in the templates it uses to the custom values. This means that in the unlikely event
9+
you're expecting to use `{{` or `}}` to signify something in your custom-interpolation-symbol application, then inside the grid your stuff will likely break.
10+
11+
<example module="app">
12+
<file name="app.js">
13+
var app = angular.module('app', ['ngAnimate', 'ui.grid']);
14+
15+
app.config(function($interpolateProvider) {
16+
$interpolateProvider.startSymbol('[[');
17+
$interpolateProvider.endSymbol(']]');
18+
});
19+
20+
app.controller('MainCtrl', ['$scope', '$http', '$interpolate', function ($scope, $http, $interpolate) {
21+
$scope.foo = 'whoohoo!';
22+
$scope.startSym = $interpolate.startSymbol();
23+
$scope.endSym = $interpolate.endSymbol();
24+
25+
$scope.gridOptions = {
26+
enableSorting: true,
27+
columnDefs: [
28+
{ field: 'name' },
29+
{ field: 'gender' },
30+
{ field: 'company', enableSorting: false }
31+
]
32+
};
33+
34+
$http.get('/data/100.json')
35+
.success(function(data) {
36+
$scope.gridOptions.data = data;
37+
});
38+
}]);
39+
</file>
40+
<file name="index.html">
41+
<div ng-controller="MainCtrl">
42+
This app uses [[ startSym ]] and [[ endSym ]] for interpolation symbols: [[ foo ]]
43+
<br>
44+
<br>
45+
<div ui-grid="gridOptions" class="grid"></div>
46+
</div>
47+
</file>
48+
<file name="main.css">
49+
.grid {
50+
width: 500px;
51+
height: 300px;
52+
}
53+
</file>
54+
</example>

src/js/core/services/ui-grid-util.js

+22-7
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ var uidPrefix = 'uiGrid-';
139139
*
140140
* @description Grid utility functions
141141
*/
142-
module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateCache', '$timeout', '$injector', '$q', 'uiGridConstants',
143-
function ($log, $window, $document, $http, $templateCache, $timeout, $injector, $q, uiGridConstants) {
142+
module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateCache', '$timeout', '$injector', '$q', '$interpolate', 'uiGridConstants',
143+
function ($log, $window, $document, $http, $templateCache, $timeout, $injector, $q, $interpolate, uiGridConstants) {
144144
var s = {
145145

146146
getStyles: getStyles,
@@ -315,25 +315,25 @@ module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateC
315315
getTemplate: function (template) {
316316
// Try to fetch the template out of the templateCache
317317
if ($templateCache.get(template)) {
318-
return $q.when($templateCache.get(template));
318+
return s.postProcessTemplate($templateCache.get(template));
319319
}
320320

321321
// See if the template is itself a promise
322322
if (template.hasOwnProperty('then')) {
323-
return template;
323+
return template.then(s.postProcessTemplate);
324324
}
325325

326326
// If the template is an element, return the element
327327
try {
328328
if (angular.element(template).length > 0) {
329-
return $q.when(template);
329+
return $q.when(template).then(s.postProcessTemplate);
330330
}
331331
}
332332
catch (err){
333333
//do nothing; not valid html
334334
}
335335

336-
$log.debug('Fetching url', template);
336+
s.logDebug('fetching url', template);
337337

338338
// Default to trying to fetch the template as a url with $http
339339
return $http({ method: 'GET', url: template})
@@ -347,7 +347,22 @@ module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateC
347347
function (err) {
348348
throw new Error("Could not get template " + template + ": " + err);
349349
}
350-
);
350+
)
351+
.then(s.postProcessTemplate);
352+
},
353+
354+
//
355+
postProcessTemplate: function (template) {
356+
var startSym = $interpolate.startSymbol(),
357+
endSym = $interpolate.endSymbol();
358+
359+
// If either of the interpolation symbols have been changed, we need to alter this template
360+
if (startSym !== '{{' || endSym !== '}}') {
361+
template = template.replace(/\{\{/g, startSym);
362+
template = template.replace(/\}\}/g, endSym);
363+
}
364+
365+
return $q.when(template);
351366
},
352367

353368
/**

test/unit/core/services/ui-grid-util.spec.js

+103-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
describe('ui.grid.utilService', function() {
22
var gridUtil,
33
$window,
4-
Grid;
4+
Grid,
5+
$rootScope,
6+
$q,
7+
$interpolateProvider;
58

6-
beforeEach(module('ui.grid'));
9+
beforeEach(module('ui.grid', function (_$interpolateProvider_) {
10+
$interpolateProvider = _$interpolateProvider_;
11+
}));
712

8-
beforeEach(inject(function(_gridUtil_, _$window_, _Grid_) {
13+
beforeEach(inject(function(_$rootScope_, _$q_, _gridUtil_, _$window_, _Grid_) {
914
gridUtil = _gridUtil_;
1015
$window = _$window_;
1116
Grid = _Grid_;
17+
$rootScope = _$rootScope_;
18+
$q = _$q_;
1219
}));
1320

1421
describe('newId()', function() {
@@ -396,4 +403,97 @@ describe('ui.grid.utilService', function() {
396403
expect(uid3).toEqual('uiGrid-003');
397404
});
398405
});
406+
407+
describe('postProcessTemplate', function () {
408+
it('should return unmodified template when interpolation symbols are the default values ( {{ / }} )', function () {
409+
var tmpl;
410+
gridUtil.getTemplate('ui-grid/ui-grid')
411+
.then(function (template) {
412+
tmpl = template;
413+
});
414+
415+
$rootScope.$digest();
416+
417+
expect(tmpl).toMatch(/\{\{/, 'template has default start interpolation symbols');
418+
expect(tmpl).toMatch(/\}\}/, 'template has default end interpolation symbols');
419+
});
420+
421+
describe('with different interpolation symbols', function () {
422+
beforeEach(function () {
423+
$interpolateProvider.startSymbol('[[');
424+
$interpolateProvider.endSymbol(']]');
425+
});
426+
427+
it('should alter templates already in $templateCache', function () {
428+
var tmpl;
429+
gridUtil.getTemplate('ui-grid/ui-grid')
430+
.then(function (template) {
431+
tmpl = template;
432+
});
433+
434+
$rootScope.$digest();
435+
436+
expect(tmpl).not.toMatch(/\{\{/, 'template does not have default start interpolation symbols');
437+
expect(tmpl).not.toMatch(/\}\}/, 'template does not have default end interpolation symbols');
438+
439+
expect(tmpl).toMatch(/\[\[/, 'template has custom start interpolation symbols');
440+
expect(tmpl).toMatch(/\]\]/, 'template has custom end interpolation symbols');
441+
});
442+
443+
it('should alter template that is just an element', function () {
444+
var tmpl;
445+
gridUtil.getTemplate('<div>{{ foo }}</div>')
446+
.then(function (template) {
447+
tmpl = template;
448+
});
449+
450+
$rootScope.$digest();
451+
452+
expect(tmpl).not.toMatch(/\{\{/, 'template does not have default start interpolation symbols');
453+
expect(tmpl).not.toMatch(/\}\}/, 'template does not have default end interpolation symbols');
454+
455+
expect(tmpl).toMatch(/\[\[/, 'template has custom start interpolation symbols');
456+
expect(tmpl).toMatch(/\]\]/, 'template has custom end interpolation symbols');
457+
});
458+
459+
it('should alter template that is a promise', function () {
460+
var p = $q.when('<div>{{ foo }}</div>');
461+
462+
var tmpl;
463+
gridUtil.getTemplate(p)
464+
.then(function (template) {
465+
tmpl = template;
466+
});
467+
468+
$rootScope.$digest();
469+
470+
expect(tmpl).not.toMatch(/\{\{/, 'template does not have default start interpolation symbols');
471+
expect(tmpl).not.toMatch(/\}\}/, 'template does not have default end interpolation symbols');
472+
473+
expect(tmpl).toMatch(/\[\[/, 'template has custom start interpolation symbols');
474+
expect(tmpl).toMatch(/\]\]/, 'template has custom end interpolation symbols');
475+
});
476+
477+
it('should alter template fetched with $http', inject(function ($httpBackend, $timeout) {
478+
var html = '<div>{{ foo }}</div>';
479+
var url = 'http://someUrl.html';
480+
$httpBackend.expectGET(url)
481+
.respond(html);
482+
483+
var result;
484+
gridUtil.getTemplate(url).then(function (r) {
485+
result = r;
486+
});
487+
$httpBackend.flush();
488+
489+
$httpBackend.verifyNoOutstandingRequest();
490+
491+
expect(result).not.toMatch(/\{\{/, 'template does not have default start interpolation symbols');
492+
expect(result).not.toMatch(/\}\}/, 'template does not have default end interpolation symbols');
493+
494+
expect(result).toMatch(/\[\[/, 'template has custom start interpolation symbols');
495+
expect(result).toMatch(/\]\]/, 'template has custom end interpolation symbols');
496+
}));
497+
});
498+
});
399499
});

0 commit comments

Comments
 (0)