Full working fiddle is at https://jsfiddle.net/dqhwzksx/, its a bit long so I'll take apart the relevant sections here.
The main issue is that neither angular-schema-form
nor angular-translate
know what to do with "description": "$filter('translate')('configuration.IOS_TABLET_DOWNLOAD_URL')"
on their own. We need to do the translation ourselves.
First, our schema now no longer needs to deal the filter itself:
var schema = {
"type": "object",
"title": "Sample Schema",
"properties": {
"IOS_TABLET_DOWNLOAD_URL": {
"type": "string",
"minLength": "5",
"title": "IOS_TABLET_DOWNLOAD_URL_TITLE",
"description": "IOS_TABLET_DOWNLOAD_URL_DESCRIPTION"
}
}
};
The title
and description
fields can now directly reference the translation tokens. Next, we're going to write an angular service that will retrieve this schema, but with the translations already made. I think this was the intention of your MyService
:
.factory('Schema', function ($q, $translate) {
return {
elements: function() {
var a = [];
var result = angular.copy(schema);
angular.forEach(result.properties, function (value, key) {
a.push($translate([value.title, value.description]).then(
function (translations) {
value.title = translations[value.title];
value.description = translations[value.description];
}
));
});
return $q.all(a).then(function() { return result; });
}
}
})
Lets break that down a little bit:
var a = [];
var result = angular.copy(schema);
First, we setup an array a
into which we're going to put a bunch of promises (one for each field in the schema), and we make a copy of the original schema since we'll be modifying it.
angular.forEach(result.properties, function (value, key) {
a.push($translate([value.title, value.description]).then(
function (translations) {
value.title = translations[value.title];
value.description = translations[value.description];
}
));
});
Here we're iterating over each property in the schema (just the one in this sample), requesting a translation for that property's title
and description
fields. Since $translate
returns promises, we need to attach a .then
handler to apply the translations direct into the copy of the schema once that promise resolves. Finally, the promise is also appended onto the a
array whose job it is to remember the list of all of these promises we're running.
return $q.all(a).then(function() { return result; });
Finally, we wait for all of those promises to have resolved (i.e. the translations are all complete), then return the fully translated schema object.
.controller('FormController',function ($scope, Schema) {
Schema.elements().then(function (elements) {
$scope.schema = elements;
})
$scope.model = {};
$scope.form = [
"IOS_TABLET_DOWNLOAD_URL"
];
});
The actual controller itself is rather simple, and not much different from your original. The markup in the template is not altered either.
For fun, try changing the preferred language from en
to de
:
$translateProvider.preferredLanguage('de');
EDIT
If you wanted to retrieve the schema contents from another file or service, replace the elements
method with something like:
elements: function() {
return $http.get('path/to/schema.json').then(function(response) {
var a = [];
var schema = response.data;
angular.forEach(schema.properties, function (value, key) {
a.push($translate([value.title, value.description]).then(
function (translations) {
value.title = translations[value.title];
value.description = translations[value.description];
}
));
});
return $q.all(a).then(function() { return schema; });
});
}