AngularJS 用 UI 路由器翻译

AngularJS translate with UI Router

我有一个使用 Angularjs 构建的应用程序,使用 Angularjs 翻译库 - https://angular-translate.github.io/,我已经用 UI 路由器设置它,因为当前网站已经已被 google 索引为 www.domain.com/en/us/ 等语言版本,我需要保持相同的 URL 结构。该网站有 30 多种语言,但它是一个 SPA(单页应用程序)。

以下是我的 Javascript 应用程序配置:

app.run(['$rootScope', '$translate', '$state', function ($rootScope, $translate, $state) {
    $rootScope.onChangeValue = function (e) {
        $rootScope.$broadcast("changeValue", e);
    };

    $rootScope.$on('$stateChangeSuccess', onStateChangeSuccess);

    function onStateChangeSuccess(event, toState, toParams) {
        var current = $translate.use();
        if (!current || current !== toParams.lang)
            $translate.use(toParams.lang);
    }
}]);

app.config(['$translateProvider', function ($translateProvider) {
    $translateProvider.useStaticFilesLoader({
        prefix: '../languages/locale-',
        suffix: '.json'
    });
    $translateProvider.fallbackLanguage('en');
    $translateProvider.preferredLanguage('en');
    $translateProvider.useSanitizeValueStrategy('escape');
    $translateProvider.useCookieStorage();
}]);

app.config(['$stateProvider', '$locationProvider', function ($stateProvider, $locationProvider) {
    $locationProvider.html5Mode(true);
    $locationProvider.hashPrefix('');

    $stateProvider.state('catalog', {
        url: '/{lang}',
        controller: "SudokuController",
        params: {
            lang: {
                value: function ($translate) {
                    return $translate.use();
                }
            }
        }
    });
}]);

在控制器中我有这些功能:

    app.controller("SudokuController", ['$scope', 'Chronicle', '$timeout', '$cookies', '$translate', '$state', '$stateParams', function ($scope, Chronicle, $timeout, $cookies, $translate, $state, $stateParams) {

    $scope.params = $stateParams;
    $scope.changeLanguage = function (newLang) {
        var params = angular.extend($stateParams, { lang: newLang });

        $translate.use(newLang).then(function () {
            $state.transitionTo($state.current, params, {
                reload: true, inherit: false, notify: true
            });
        });
    }
}]);

这是使用多种语言生成导航的 HTML:

<div class="language-dropdown">
    <ul class="country-list" ng-controller="navigationLanguages">
        <li class="country" ng-repeat="language in languagesMenu">
            <div class="country-flag" style="background-image: url('images/mk.png');"></div>
            <a ng-bind="language.Language" ng-click="changeLanguage(language.Code)"></a>
        </li>
    </ul>
</div>

到目前为止,我已经实现了将所选语言添加到 URL,例如,如果我点击英语,我会得到 www.domain。com/en,如果我点击西班牙语我得到 www.domain.com/es。但是当我直接转到 www.domain.com/en 时,我得到错误 404 - 找不到对象!

  1. 您的服务器代码是什么样的?我猜它只是在 "/" 上提供索引页面,所以如果您在任何不是根目录的路由上刷新您的页面,它不会提供任何东西,您将找不到。基本上对于单页应用程序,路由应该完全在客户端处理,因为这是具有关于您的应用程序的上下文以知道要做什么的部分。因此,无论使用哪条路由,始终让您的服务器提供索引页面,这将使 ui 路由器接管并发挥其魔力 ​​
  2. 要添加 /en/us,请更新您的状态配置。另外,你真的不需要定义 params 除非你需要一个默认值
$stateProvider.state('catalog', {
    url: '/{lang}/{region}',
    controller: "SudokuController"
});
  1. Google 的抓取工具可能能够抓取像您这样的单页应用程序,但大多数抓取工具不能 - 因此,如果您关心 SEO,则需要做一些额外的事情。你有几个选择
    1. https://prerender.io/ 这样的服务付费 您必须在服务器上设置一些代码,但在大多数情况下,它们会负责使您的网站可抓取。我过去使用过它们并推荐它们。它是如何工作的?基本上,当爬虫访问您的网站而不是为他们提供单页应用程序时,预呈现将为他们提供您网站的静态版本,该版本已预先呈现,爬虫可以理解。
    2. 第二个选项是 quite 一些工作。我也做过这个(但是在 angular 的较新版本上)并且不推荐它,很多令人头疼的事情。它称为服务器端渲染。基本上,不是让其他服务创建页面的预呈现版本,而是您的服务器即时执行。较新版本的 angular 有一些 built 的功能,不确定 angularjs。我建议在谷歌上搜索更多关于预渲染和服务器端渲染的信息,这里我无法说的太多了。