Недавно мне попался маленький проект, где я предложил использование Angular и XSLT, на что я получил такой вопрос: «С чего бы использовать устаревшую технологию XSLT, ведь ее используют только с Java, да к тому же, только для Enterprise»?
Этот вопрос и явился причиной того, что я решил написать данную статью.
Итак, разрешите представить вашему вниманию «химеру» под названием Angular XSLT module. Ангулар разделяет business логику и view логику, но с модулем XSLT, view логику Angular можно вообще отдать XSLT.
Есть конечно пара подводных камней, это:
1) Результат не будет рендерится,
2) Angular команды не будут вызываться.
Но легким движением руки, эти проблемы решаются на раз-два!
Итак, начнем.
Имеет следующий код:
(Заметьте, XSLT используется в качестве фильтра.)
Что в браузере рендерится как:
Hello, my name is < b xmlns=«www.w3.org/1999/xhtml»>Angular XSLT module!</b >
Негоже… Нет рендеринга, и выводится как текст. Добавляем одно легкое движение рукой, что называется «санитаризация (trustAsHtml(htmlCode))»:
Что в браузере будет как:
Hello, my name is Angular XSLT module!
Где «Angular XSLT module!» рендерится в bold.
Теперь попытаемся вызвать функцию Ангулара из текста, который выдает нам XSLT модуль, для чего мы:
1) Естественно, дописываем в XSLT вызов функции «clickMyXslt()».
2) В Angular дописываем соответствующую функцию.
3) В Angular дописываем директиву(compileTemplate) для компиляции текста, который выдает нам XSLT модуль.
Что результатирует в браузере:
Hello, my name is Angular XSLT module! <button>clickMyXslt</button>
Где, кликнув на <button/>, получаем всплывающее JS окошко:
alert(«Yes, I am from clickMyXslt function!»);
На этом все. Надеюсь по немногу мифы об устаревании XSLT станут мифами.
(*Все эти техники не я сам придумал, а выловил в интернете и соединил в одно)
Удачного всем кода!
PS: Пример такого подхода можно посмотреть здесь (видеоролик в VK).
PSS: Здесь используется AngularJS v1.4.0
Этот вопрос и явился причиной того, что я решил написать данную статью.
Итак, разрешите представить вашему вниманию «химеру» под названием Angular XSLT module. Ангулар разделяет business логику и view логику, но с модулем XSLT, view логику Angular можно вообще отдать XSLT.
Есть конечно пара подводных камней, это:
1) Результат не будет рендерится,
2) Angular команды не будут вызываться.
Но легким движением руки, эти проблемы решаются на раз-два!
Итак, начнем.
Имеет следующий код:
<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>
(Заметьте, XSLT используется в качестве фильтра.)
Что в браузере рендерится как:
Hello, my name is < b xmlns=«www.w3.org/1999/xhtml»>Angular XSLT module!</b >
Негоже… Нет рендеринга, и выводится как текст. Добавляем одно легкое движение рукой, что называется «санитаризация (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>
Что в браузере будет как:
Hello, my name is Angular XSLT module!
Где «Angular XSLT module!» рендерится в bold.
Теперь попытаемся вызвать функцию Ангулара из текста, который выдает нам XSLT модуль, для чего мы:
1) Естественно, дописываем в XSLT вызов функции «clickMyXslt()».
2) В Angular дописываем соответствующую функцию.
3) В Angular дописываем директиву(compileTemplate) для компиляции текста, который выдает нам XSLT модуль.
<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>
Что результатирует в браузере:
Hello, my name is Angular XSLT module! <button>clickMyXslt</button>
Где, кликнув на <button/>, получаем всплывающее JS окошко:
alert(«Yes, I am from clickMyXslt function!»);
На этом все. Надеюсь по немногу мифы об устаревании XSLT станут мифами.
(*Все эти техники не я сам придумал, а выловил в интернете и соединил в одно)
Удачного всем кода!
PS: Пример такого подхода можно посмотреть здесь (видеоролик в VK).
PSS: Здесь используется AngularJS v1.4.0
