I have a localization component that looks like this:
(function() {
'use strict';
angular
.module('app.core')
.component('i18n', {
templateUrl: './i18n.html',
bindings: {
code: '@'
},
controller: i18n,
controllerAs: 'vm'
});
i18n.$inject = ['langStrings'];
function i18n(langStrings) {
const vm = this;
this.$onInit = () => {
vm.text = langStrings.get(vm.code);
};
}
})();
The i18n template consists of a single line:
{{vm.text}}
This works great for displaying strings, but when I want to use the string in another component or in template as a placeholder for input tag, I don't know how to apply it. So for example how would I apply the components end result for inputs placeholder in another context?
Input in some other component or template.
<input
placeholder="<i18n code='searchPlaceholder'/>"
>
I am using angularJs 1.7.2
Input placeholder attribute is waiting for a string. <i18n>
is a component rendering an HTML element like its name (restriction in directives as Element witch component actually acts).
Angular can support interpolation on an attribute. so basically, you need to create something like placeholder="{{exp}}"
witch the exp evaluation will have to return a string.
{{langStrings.get(v)}}
and cast it to a var so use placeholder="{{vm.text}}"
or ng-init="z= lngs('asdf');" placeholder="{{z}}"
try an easier way to change elements attribute on a directive using the link function
(function() {
'use strict';
function i18n(langStrings) {
return {
restrict: 'CA',
scope: {
code: '@'
},
link: function(scope, elem, attrs) {
//attrs.$set('placeholder', langStrings.get(scope.code));
// observe changes to interpolated attribute
attrs.$observe('code', function(value) {
let text = langStrings.get(value);
elem.attr('placeholder', text);
});
//https://stackoverflow.com/questions/14876112/angularjs-difference-between-the-observe-and-watch-methods
//scope.$watch('code', function(newval) {
//let text = langStrings.get(newval);
//elem.attr('placeholder', text);
//});
},
}
}
function testCtrl($scope, langStrings) {
$scope.lngs = function(v) {
return langStrings.get(v);
};
return this;
}
angular
.module('app', [])
.component('i18c', {
bindings: {
code: '@'
},
template: function($element, $attrs, langStrings) {
let c = langStrings.get($attrs.code);
return `<input placeholder="` + c + `">`;
}
})
.directive('i18nCustom', i18n)
.controller('testCtrl', testCtrl)
//i18n.$inject = ['langStrings'];
.factory('langStrings', function() {
this.get = (v) => {
return v + '-transformed';
};
return this;
})
})();
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.js"></script>
<body ng-app="app" ng-controller="testCtrl">
<input class="i18n-custom" code='test-class'>
<input i18n-custom code='test-attr'>
<input ng-init="z = lngs('test ctrl fun');" placeholder="{{z}}">
<i18c code="Test Comp"></i18c>
</body>