Как использовать проверку angular-translate и ng-xeditable вместе?

Я использую angular-translate и angular-xeditable. У меня есть следующее поле:

<a href="#"
       editable-text="name"
       onbeforesave="validate($data)"
       onaftersave="save(name)">
       {{ name }}
</a>

В функции validate я проверяю поле name и, если все правильно, я сохраняю данные с помощью метода сохранения. Однако, если поле name указано неверно, я должен вернуть сообщение проверки. В документации angular-xeditable такого сценария есть пример.

$scope.validate = function(name) {
    if (name.length > 10) {
        return "Validation Message that doesn't need multiple languages";
    }
}

Теперь, если длина поля name превышает 10 символов, пользователю будет показано сообщение, а данные не будут сохранены. Однако я использую angular-translate в своем приложении и хочу показать сообщение, переведенное на соответствующий язык. Более того, я хочу настроить свои сообщения для разных сценариев, чтобы мне не нужно было иметь тысячи разных сообщений для всех моих полей.

Например:

var translationsEN = {
    STRING_LENGTH_MESSAGE: '{{ fieldName }} should be between {{ min }} and {{ max }}',
    REQUIRED: '{{ fieldName }} is required.'
}
var translationsDE = {
    // The same messages in German.
}

Теперь лучшее, что я мог придумать, это изменить код в функции проверки на это:

$scope.validate = function(name) {
    if (name.length > 10) {
        $translate('VALIDATION_MESSAGE', { fieldName: 'name', min: 0, max: 10 })
            .then(function(translation) {
                $scope.message = translation;
            }
        );

        return $scope.message;
    }
}

Конечно, во время отображения сообщения об ошибке сообщение об ошибке еще не переведено, и сообщение, отображаемое пользователю, неверно.

Как я могу добиться желаемого результата - показать пользователю переведенные сообщения проверки?

Вот JSFiddle моего примера.


person Yulian    schedule 10.12.2015    source источник


Ответы (1)


Сегодня потратил на это приличное количество часов :)

Что кажется обходным путем, так это компиляция элемента, который будет иметь директиву translate, поэтому функция OP будет выглядеть примерно так:

$scope.validateName = function(name) {
    if (name.length > 10) {
      console.log('fail')
      var element = $compile('<span translate="VALIDATION_MESSAGE"></span>')($scope)[0];
      return $timeout(function() {
        $scope.$apply();
        return element.textContent
      }, 10);
    }
  };

Еще немного о компиляции и динамическом добавлении директив (что тоже помогло бы решить задачу — если бы мы могли динамически устанавливать директиву translate в контейнер ошибок) — в ответах на этот вопрос: Динамическое добавление директивы в AngularJS

ОБНОВЛЕНИЕ: немного изменил код, чтобы он работал с проверкой имени в контроллере. $timeout может не понадобиться, если проверка выполняется на сервере, но в этом случае было бы невозможно использовать $scope.$apply() иначе, без которого результат не будет интерполирован.

Работает JSFiddle — первый ввод проверяется способом OP, второй — функцией выше .

Надеюсь, поможет.

person a-change    schedule 20.12.2017