Skip to content

Commit

Permalink
feat(Interpolation): Handle custom symbols
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
c0bra committed Nov 7, 2014
1 parent a3f3f7e commit 555ddec
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 10 deletions.
54 changes: 54 additions & 0 deletions misc/tutorial/313_custom_interpolation_symbols.ngdoc
@@ -0,0 +1,54 @@
@ngdoc overview
@name Tutorial: 313 Custom Interpolation Symbols
@description

Combining AngularJS with other frameworks/tools sometimes requires changing the normal interpolation symbols (`{{` and `}}`) to something else, like `[[` or `%`.
<br>
<br>
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
you're expecting to use `{{` or `}}` to signify something in your custom-interpolation-symbol application, then inside the grid your stuff will likely break.

<example module="app">
<file name="app.js">
var app = angular.module('app', ['ngAnimate', 'ui.grid']);

app.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});

app.controller('MainCtrl', ['$scope', '$http', '$interpolate', function ($scope, $http, $interpolate) {
$scope.foo = 'whoohoo!';
$scope.startSym = $interpolate.startSymbol();
$scope.endSym = $interpolate.endSymbol();

$scope.gridOptions = {
enableSorting: true,
columnDefs: [
{ field: 'name' },
{ field: 'gender' },
{ field: 'company', enableSorting: false }
]
};

$http.get('/data/100.json')
.success(function(data) {
$scope.gridOptions.data = data;
});
}]);
</file>
<file name="index.html">
<div ng-controller="MainCtrl">
This app uses [[ startSym ]] and [[ endSym ]] for interpolation symbols: [[ foo ]]
<br>
<br>
<div ui-grid="gridOptions" class="grid"></div>
</div>
</file>
<file name="main.css">
.grid {
width: 500px;
height: 300px;
}
</file>
</example>
29 changes: 22 additions & 7 deletions src/js/core/services/ui-grid-util.js
Expand Up @@ -139,8 +139,8 @@ var uidPrefix = 'uiGrid-';
*
* @description Grid utility functions
*/
module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateCache', '$timeout', '$injector', '$q', 'uiGridConstants',
function ($log, $window, $document, $http, $templateCache, $timeout, $injector, $q, uiGridConstants) {
module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateCache', '$timeout', '$injector', '$q', '$interpolate', 'uiGridConstants',
function ($log, $window, $document, $http, $templateCache, $timeout, $injector, $q, $interpolate, uiGridConstants) {
var s = {

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

// See if the template is itself a promise
if (template.hasOwnProperty('then')) {
return template;
return template.then(s.postProcessTemplate);
}

// If the template is an element, return the element
try {
if (angular.element(template).length > 0) {
return $q.when(template);
return $q.when(template).then(s.postProcessTemplate);
}
}
catch (err){
//do nothing; not valid html
}

$log.debug('Fetching url', template);
s.logDebug('fetching url', template);

// Default to trying to fetch the template as a url with $http
return $http({ method: 'GET', url: template})
Expand All @@ -347,7 +347,22 @@ module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateC
function (err) {
throw new Error("Could not get template " + template + ": " + err);
}
);
)
.then(s.postProcessTemplate);
},

//
postProcessTemplate: function (template) {
var startSym = $interpolate.startSymbol(),
endSym = $interpolate.endSymbol();

// If either of the interpolation symbols have been changed, we need to alter this template
if (startSym !== '{{' || endSym !== '}}') {
template = template.replace(/\{\{/g, startSym);
template = template.replace(/\}\}/g, endSym);
}

return $q.when(template);
},

/**
Expand Down
106 changes: 103 additions & 3 deletions test/unit/core/services/ui-grid-util.spec.js
@@ -1,14 +1,21 @@
describe('ui.grid.utilService', function() {
var gridUtil,
$window,
Grid;
Grid,
$rootScope,
$q,
$interpolateProvider;

beforeEach(module('ui.grid'));
beforeEach(module('ui.grid', function (_$interpolateProvider_) {
$interpolateProvider = _$interpolateProvider_;
}));

beforeEach(inject(function(_gridUtil_, _$window_, _Grid_) {
beforeEach(inject(function(_$rootScope_, _$q_, _gridUtil_, _$window_, _Grid_) {
gridUtil = _gridUtil_;
$window = _$window_;
Grid = _Grid_;
$rootScope = _$rootScope_;
$q = _$q_;
}));

describe('newId()', function() {
Expand Down Expand Up @@ -396,4 +403,97 @@ describe('ui.grid.utilService', function() {
expect(uid3).toEqual('uiGrid-003');
});
});

describe('postProcessTemplate', function () {
it('should return unmodified template when interpolation symbols are the default values ( {{ / }} )', function () {
var tmpl;
gridUtil.getTemplate('ui-grid/ui-grid')
.then(function (template) {
tmpl = template;
});

$rootScope.$digest();

expect(tmpl).toMatch(/\{\{/, 'template has default start interpolation symbols');
expect(tmpl).toMatch(/\}\}/, 'template has default end interpolation symbols');
});

describe('with different interpolation symbols', function () {
beforeEach(function () {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});

it('should alter templates already in $templateCache', function () {
var tmpl;
gridUtil.getTemplate('ui-grid/ui-grid')
.then(function (template) {
tmpl = template;
});

$rootScope.$digest();

expect(tmpl).not.toMatch(/\{\{/, 'template does not have default start interpolation symbols');
expect(tmpl).not.toMatch(/\}\}/, 'template does not have default end interpolation symbols');

expect(tmpl).toMatch(/\[\[/, 'template has custom start interpolation symbols');
expect(tmpl).toMatch(/\]\]/, 'template has custom end interpolation symbols');
});

it('should alter template that is just an element', function () {
var tmpl;
gridUtil.getTemplate('<div>{{ foo }}</div>')
.then(function (template) {
tmpl = template;
});

$rootScope.$digest();

expect(tmpl).not.toMatch(/\{\{/, 'template does not have default start interpolation symbols');
expect(tmpl).not.toMatch(/\}\}/, 'template does not have default end interpolation symbols');

expect(tmpl).toMatch(/\[\[/, 'template has custom start interpolation symbols');
expect(tmpl).toMatch(/\]\]/, 'template has custom end interpolation symbols');
});

it('should alter template that is a promise', function () {
var p = $q.when('<div>{{ foo }}</div>');

var tmpl;
gridUtil.getTemplate(p)
.then(function (template) {
tmpl = template;
});

$rootScope.$digest();

expect(tmpl).not.toMatch(/\{\{/, 'template does not have default start interpolation symbols');
expect(tmpl).not.toMatch(/\}\}/, 'template does not have default end interpolation symbols');

expect(tmpl).toMatch(/\[\[/, 'template has custom start interpolation symbols');
expect(tmpl).toMatch(/\]\]/, 'template has custom end interpolation symbols');
});

it('should alter template fetched with $http', inject(function ($httpBackend, $timeout) {
var html = '<div>{{ foo }}</div>';
var url = 'http://someUrl.html';
$httpBackend.expectGET(url)
.respond(html);

var result;
gridUtil.getTemplate(url).then(function (r) {
result = r;
});
$httpBackend.flush();

$httpBackend.verifyNoOutstandingRequest();

expect(result).not.toMatch(/\{\{/, 'template does not have default start interpolation symbols');
expect(result).not.toMatch(/\}\}/, 'template does not have default end interpolation symbols');

expect(result).toMatch(/\[\[/, 'template has custom start interpolation symbols');
expect(result).toMatch(/\]\]/, 'template has custom end interpolation symbols');
}));
});
});
});

0 comments on commit 555ddec

Please sign in to comment.