📜 ⬆️ ⬇️

Angular XSLT module

Recently I came across a small project, where I proposed using Angular and XSLT, to which I received the following question: “Why use outdated XSLT technology, because it is used only with Java, and besides, only for Enterprise”?

This question was the reason that I decided to write this article.

So let me introduce to your attention a “chimera” called Angular XSLT module . Angular shares business logic and view logic, but with the XSLT module, view Angular logic can generally be given away to XSLT.
')
There are of course a couple of pitfalls, this is:

1) The result will not be rendered,
2) Angular commands will not be called.

But with a flick of the wrist, these problems are solved once or twice!

So, let's begin.

It has the following code:

<html> <body ng-app="app"> <div ng-controller="ExampleController"> <pre>{{xml | xslt:xslt}}</pre> </div> <script src="angular.js"></script> <script src="ng-xslt.js"></script> <script> var myApp = angular.module('app', ['ngXslt']); myApp.controller('ExampleController', ['$scope',function ($scope) { $scope.xml ='<?xml version="1.0" encoding="UTF-8"?><root><name>Angular XSLT module!</name></root>'; $scope.xslt = '<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:output method="html"/><xsl:template match="/"><xsl:text>Hello, my name is </xsl:text><b><xsl:value-of select="root/name"/></b></xsl:template></xsl:stylesheet>'; } ]); </script> </body> </html> 

(Note, XSLT is used as a filter.)

What the browser renders as:

Hello, my name is <b xmlns = " www.w3.org/1999/xhtml "> Angular XSLT module! </ B>

It is not good ... No rendering, and output as text. Add one light movement with your hand, which is called "sanitation (trustAsHtml (htmlCode))":

 <html> <body ng-app="app"> <div ng-controller="ExampleController"> <div ng-bind-html="xml | xslt:xslt | sanitize"></div> </div> <script src="angular.js"></script> <script src="ng-xslt.js"></script> <script> var myApp = angular.module('app', ['ngXslt']); myApp.controller('ExampleController', ['$scope',function ($scope) { $scope.xml ='<?xml version="1.0" encoding="UTF-8"?><root><name>Angular XSLT module!</name></root>'; $scope.xslt = '<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:output method="html"/><xsl:template match="/"><xsl:text>Hello, my name is </xsl:text><b><xsl:value-of select="root/name"/></b></xsl:template></xsl:stylesheet>'; } ]); myApp.filter("sanitize", ['$sce', function($sce) { return function(htmlCode){ return $sce.trustAsHtml(htmlCode); } }]); </script> </body> </html> 

What the browser will be like:

Hello, my name is Angular XSLT module!

Where the “Angular XSLT module!” Is rendered in bold .

Now we will try to call the Angulara function from the text that the XSLT module gives us, for which we:

1) Naturally, in XSLT we add a call to the function “clickMyXslt ()”.
2) In Angular, we add the corresponding function.
3) In Angular, we add a directive (compileTemplate) to compile the text that the XSLT module gives us.

 <html> <body ng-app="app"> <div ng-controller="ExampleController"> <div ng-bind-html="xml | xslt:xslt | sanitize" compile-template></div> </div> <script src="angular.js"></script> <script src="ng-xslt.js"></script> <script> var myApp = angular.module('app', ['ngXslt']); myApp.controller('ExampleController', ['$scope',function ($scope) { $scope.xml ='<?xml version="1.0" encoding="UTF-8"?><root><name>Angular XSLT module!</name></root>'; $scope.xslt = '<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform" version="1.0" ><xsl:output method="html"/><xsl:template match="/"><xsl:text>Hello, my name is </xsl:text><b><xsl:value-of select="root/name"/></b><input type="button" ng-click="clickMyXslt()" value="clickMyXslt"/></xsl:template></xsl:stylesheet>'; $scope.clickMyXslt = function() { alert("Yes, I am from clickMyXslt function!"); }; } ]); myApp.filter("sanitize", ['$sce', function($sce) { return function(htmlCode){ return $sce.trustAsHtml(htmlCode); } }]); myApp.directive('compileTemplate', function($compile, $parse){ return { link: function(scope, element, attr){ var parsed = $parse(attr.ngBindHtml); function getStringValue() { return (parsed(scope) || '').toString(); } //Recompile if the template changes scope.$watch(getStringValue, function() { $compile(element, null, -9999)(scope); //The -9999 makes it skip directives so that we do not recompile ourselves }); } } }); </script> </body> </html> 

What results in the browser:

Hello, my name is Angular XSLT module! <button> clickMyXslt </ button>

Where, by clicking on <button />, we get a pop-up JS window:

alert ("Yes, I am from clickMyXslt function!");

That's all. I hope by few myths about the obsolescence of XSLT will become myths.

(* I did not invent all these techniques myself, but caught them on the Internet and put them into one)

Good luck to all the code!

PS: An example of this approach can be found here (video in VK) .

PSS: It uses AngularJS v1.4.0

Source: https://habr.com/ru/post/268825/


All Articles