Skip to content

Instantly share code, notes, and snippets.

@idosela
Last active February 25, 2024 12:51
Show Gist options
  • Save idosela/8421332 to your computer and use it in GitHub Desktop.
Save idosela/8421332 to your computer and use it in GitHub Desktop.
Sample code for ng-conf 2014
angular.module('myMdl', []).config(['$httpProvider', function($httpProvider) {
$httpProvider.responseInterceptors.push([
'$q', '$templateCache', 'activeProfile',
function($q, $templateCache, activeProfile) {
// Keep track which HTML templates have already been modified.
var modifiedTemplates = {};
// Tests if there are any keep/omit attributes.
var HAS_FLAGS_EXP = /data-(keep|omit)/;
// Tests if the requested url is a html page.
var IS_HTML_PAGE = /\.html$|\.html\?/i;
return function(promise) {
return promise.then(function(response) {
var url = response.config.url,
responseData = response.data;
if (!modifiedTemplates[url] && IS_HTML_PAGE.test(url) &&
HAS_FLAGS_EXP.test(responseData)) {
// Create a DOM fragment from the response HTML.
var template = $('<div>').append(responseData);
// Find and parse the keep/omit attributes in the view.
template.find('[data-keep],[data-omit]').each(function() {
var element = $(this),
data = element.data(),
keep = data.keep,
features = keep || data.omit || '';
// Check if the user has all of the specified features.
var hasFeature = _.all(features.split(','), function(feature) {
return activeProfile.features[feature];
});
if (flags.features.length &&
((keep && !hasFeature) || (!keep && hasFeature))) {
element.remove();
}
});
// Set the modified template.
response.data = template.html();
// Replace the template in the template cache, and mark the
// template as modified.
$templateCache.put(url, response.data);
modifiedTemplates[url] = true;
}
return response;
},
// Reject the response in case of an error.
function(response) {
return $q.reject(response);
});
};
}]);
}]);
@ryanzec
Copy link

ryanzec commented Jan 17, 2014

would this gain any performance compared to just doing ng-if since from my understanding, angular will not process anything within an if statement that is evaluates to false?

@ziaxdk
Copy link

ziaxdk commented Jan 17, 2014

ng-if will remove the dom element, which this doesn't

@torifat
Copy link

torifat commented Jan 18, 2014

Is there any benefit in not doing it with a custom directive? If I were to do this, I would parse them in request interceptor instead the response. So, that I can tell the server not to send me unnecessary data.

@sebastienbarre
Copy link

Can't the user just use Firebug or any debugging tools to inspect the result of the XHR request, before the data-keep bits are removed by Angular?

@ryanzec
Copy link

ryanzec commented Jan 20, 2014

@ziaxdk, This actually removes the DOM element from the template before it even gets to angular so technically using this would remove the need for angular to process the ngIf.

@sebastienbarre I believe you are correct on that however this for me is more about performance gains than hiding HTML from the user.

To answer my own question, I guess this would be more performant then just using ngIf since it would remove the need to process the ngIf on each update of the DOM instead of just once per template.

@hasdavidc
Copy link

Why make Angular process/evaluate extra directives (even if you wrote a very performant one) when you don't need to? It is a point/question of performance.

There may be somewhat of a security gain (in that it's a bit more obfuscated from the user), but @sebastienbarre is right in that it's not exactly enough - but security is not the primary intention of this pattern. (The user could just examine the XHR response. You could load templates into the $templateCache beforehand using a Grunt task like ng-templates, but the user could still examine the $templateCache.)

@stryju
Copy link

stryju commented Feb 18, 2014

@hasdavidc @torifat the benefit? cache! you grab the same template for different set of, let's say, options

watch http://www.youtube.com/watch?v=62RvRQuMVyg for more ;-)

@gaboesquivel
Copy link

👍

@ryanzec
Copy link

ryanzec commented Aug 30, 2014

Just updated my fork of this that is compatible with angular 1.3.x (since $httpProvider.responseInterceptors in no longer valid) : https://gist.github.com/ryanzec/8461975

@ashclarke
Copy link

Has anyone noticed that flags for the test flags.features.length is not defined? Should this be just features.length?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment