【问题标题】:Using Angular translate within controller, for data brought by service在控制器中使用 Angular translate,用于服务带来的数据
【发布时间】:2015-11-30 19:24:46
【问题描述】:

我有以下场景:

我有一个包含此类数据的 JSON 文件:

"IOS_TABLET_DOWNLOAD_URL": {
  "type": "string",
  "minLength": "5",
  "title": "IOS_TABLET_DOWNLOAD_URL",
  "description": "$filter('translate')('configuration.IOS_TABLET_DOWNLOAD_URL')"
},

描述字段需要使用Angular Translate 进行翻译,我正在将服务注入到我的控制器中

ConfigController.$inject = ['$scope', '$filter', '$compile', 'MyService'];
function ConfigController($scope, $filter, $compile, MyService) {

  // And using compile
  $scope.schema = elements; // Where element is the object from MyService
  $compile($scope.schema)($scope);

}

但是 $filter 被打印为视图中的描述,未经处理

"$filter('translate')('configuration.IOS_TABLET_DOWNLOAD_URL')"

编辑

我正在使用Angular Schema Form 生成表单。所以基本上我的观点是这样的

<div ng-controller="FormController">
   <form sf-schema="schema" sf-form="form" sf-model="model"></form>
</div>

我该怎么做?

【问题讨论】:

  • 你的观点是什么?我们只能猜测,直到你给我们。
  • 更新问题
  • @DannyG 你还有这个解决方案吗?
  • @nicknystrom 是的,赏金正在为此进行
  • 模式 JSON 是通过 ajax 获取的吗?还是它只是静态 javascript 中的一个结构?

标签: javascript angularjs json angular-translate angular-schema-form


【解决方案1】:

完整的工作小提琴在https://jsfiddle.net/dqhwzksx/,它有点长,所以我将在这里分解相关部分。

主要问题是angular-schema-formangular-translate 都不知道自己如何处理"description": "$filter('translate')('configuration.IOS_TABLET_DOWNLOAD_URL')"。我们需要自己翻译。

首先,我们的模式现在不再需要处理过滤器本身:

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"
        }
    }
};

titledescription 字段现在可以直接引用翻译标记。接下来,我们将编写一个 Angular 服务来检索这个模式,但已经进行了翻译。我想这是你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; });
        }
    }
})

让我们稍微分解一下:

var a = [];
var result = angular.copy(schema);

首先,我们设置了一个数组a,我们将在其中放入一堆承诺(模式中的每个字段一个),并且我们复制原始模式,因为我们将对其进行修改.

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];
        }
    ));
});

在这里,我们遍历架构中的每个属性(仅本示例中的一个),请求翻译该属性的 titledescription 字段。由于$translate 返回承诺,我们需要附加一个.then 处理程序,以便在承诺解决后将翻译直接应用到模式的副本中。最后,promise 附加到 a 数组中,它的任务是记住我们正在运行的所有这些 promise 的列表。

return $q.all(a).then(function() { return result; });

最后,我们等待所有这些承诺都已解决(即翻译全部完成),然后返回完全翻译的架构对象。

.controller('FormController',function ($scope, Schema) {

    Schema.elements().then(function (elements) {
        $scope.schema = elements;
    })
    $scope.model = {};
    $scope.form = [
        "IOS_TABLET_DOWNLOAD_URL"
    ];

});

实际的控制器本身是相当简单的,和你原来的没有太大区别。模板中的标记也没有改变。

为了好玩,请尝试将首选语言从 en 更改为 de

$translateProvider.preferredLanguage('de');

编辑

如果您想从另一个文件或服务中检索架构内容,请将 elements 方法替换为以下内容:

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; });
    });
}

【讨论】:

  • @DannyG:这个解决方案对你有帮助吗?
  • 我在工作的时候,这不是一个工作项目,我会尝试然后给你反馈
  • 我使用的是外部 .json 文件,你如何在这个工厂中读取外部文件?这就是我得到服务的原因,我忘了提这个
  • elements 函数替换为使用$http.get 检索架构内容的修改版本。
  • 所以,我只是摆脱了 .service.js 文件,只使用工厂?
【解决方案2】:

我刚刚意识到,description 属性是一个字符串。我没有理由看到它会打印其他任何东西。 JSON 并不真正意味着承载功能,只是数据(否则它只是普通的 JS)。只需传递您要过滤的数据并将其替换为最终结果即可。

【讨论】:

  • 你到底是什么意思?
  • IOS_TABLET_DOWNLOAD_URL 中,属性description 用引号引起来; JSON 不能传输可用的函数,除非你打算使用 eval()(不要那样做)。我建议不要包含您想要进行的函数调用的文字字符串,而是传输您可以在流程图中选择或执行某些预定操作的关键字。
  • 我也想过 eval 函数,但根本不想使用它。但你是对的,我必须想一个合适的解决方案
  • 您是否知道description 可能需要通过翻译过滤器,或者可能的内容类型非常多样化?最起码,您是否首先可以控制提供它的资源?
  • 我必须尝试未知,这个想法是一个集成团队(某种后端,修改模式和表单,他们还可以使用 i18n 键修改 json 文件,所以它可以是N个未知键
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-06
  • 2015-10-15
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多