9

I'm trying to do a variable replacement while also making it clickable with ngClick.

I made a plunker demo (click the button and observe that the input box stays unchanged)

Markup:

<body ng-controller="Ctrl"> <input type="text" id="input" name="input" ng-model="myValue" test> <p translate="VARIABLE_REPLACEMENT" translate-values="{{ 'translationData' }}"></p> <p ng-bind-html="alink"></p> </body> 

Angular stuff:

var translations = { VARIABLE_REPLACEMENT: 'Hi, {{name}}' }; var app = angular.module('myApp', ['pascalprecht.translate', 'ngSanitize']); app.config(['$translateProvider', function ($translateProvider) { // add translation table $translateProvider.translations(translations); }]); app.controller('Ctrl', ['$scope', '$sce', function ($scope, $sce) { $scope.translationData = { name: 'foo'}; $scope.setValue = function(value) { $scope.myValue = value; }; }]); app.directive('test', ['$translate', '$sce', function ($translate, $sce) { return { require: 'ngModel', scope: false, link: function (scope, element, attrs, ctrl) { scope.$watch(attrs.ngModel, function (value) { var a = $translate('VARIABLE_REPLACEMENT', { name: '<button type="button" ng-click="setValue(\'foobar\')">click me</button>' }); scope.alink = $sce.trustAsHtml(a); }); } }; }]); 

The question is: Why doesn't ng-click="setValue('foobar')" fire when the button is clicked. It's supposed to set the value 'foobar' in the input field.

3 Answers 3

10

In the meanwhile there is an official solution to that problem:

<p translate="varWithDirective" translate-compile></p> 

would do the compilation without the need of writing a custom directive.

For more info: https://github.com/angular-translate/angular-translate/issues/184

Sign up to request clarification or add additional context in comments.

Comments

10

Angular doesn't $compile the $sce markup. So Angular hasn't processed your ng-click and attached the directive to it.

In order to use Angular directives inside your string, and have them live, you'll need to send the string to Angular's $compile function.

One easy way to do this is to use the following directive (found here:https://github.com/angular/angular.js/issues/4992)

Using this you'll replace:

<p ng-bind-html="alink"></p> 

with

<p compile="alink"></p> 

And add this directive:

angularApp.directive('compile', function($compile) { // directive factory creates a link function return function(scope, element, attrs) { scope.$watch( function(scope) { // watch the 'compile' expression for changes return scope.$eval(attrs.compile); }, function(value) { // when the 'compile' expression changes // assign it into the current DOM element.html(value); // compile the new DOM and link it to the current // scope. // NOTE: we only compile .childNodes so that // we don't get into infinite loop compiling ourselves $compile(element.contents())(scope); } ); }; 

});

Comments

1

You created an element outside of angular. I'm not sure how pascalprescht works but you're going to need to tell the element to $compile (docs)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.