Javascript RequireJS:如何向路径添加前缀

Javascript RequireJS:如何向路径添加前缀,javascript,html,knockout.js,requirejs,single-page-application,Javascript,Html,Knockout.js,Requirejs,Single Page Application,我正在使用Knockout.jsv3和RequireJS开发一个SPA 我有这样的写作: define(['text!settings.html'], function( htmlString) { 'use strict'; function SettingsViewModel(params) { ... } // Return component definition return {

我正在使用Knockout.jsv3和RequireJS开发一个SPA

我有这样的写作:

define(['text!settings.html'],
    function( htmlString) {
        'use strict';

       function SettingsViewModel(params) {
           ...
       }
        // Return component definition
        return {
            viewModel: SettingsViewModel,
            template: htmlString
        };
    });
define([],
    function() {
        'use strict';

       function SettingsViewModel(params) {
           ...
       }
        // Return component definition
        return {
            viewModel: SettingsViewModel,
            template: { 
                languageUrl: 'settings.html',
                language: 'nl' // overwrite default
            }
        };
    });
现在我想支持本地化,为此,我为每种受支持的语言复制了html,例如:

en/settings.html
de/settings.html
se/settings.html
我想让用户更改一种语言并用新语言刷新应用程序,是否可以指示require text plugin将语言前缀添加到所有html中,因此当我编写:

text!settings.html
它将实际加载:

text!de/settings.html

不确定是否可以让文本插件为URL添加前缀。您可以做的是创建自定义模板加载程序:

var templateFromLanguageUrlLoader = {
    loadTemplate: function(name, templateConfig, callback) {
        if (templateConfig.languageUrl) {
            // Language from config or default language
            var lang = templateConfig.lang || 'de';
            var fullUrl = lang + '/' + templateConfig.languageUrl;
            $.get(fullUrl, function(markupString) {
                ko.components.defaultLoader.loadTemplate(name, markupString, callback);
            });
        } else {
            // Unrecognized config format. Let another loader handle it.
            callback(null);
        }
    }
};

// Register it
ko.components.loaders.unshift(templateFromLanguageUrlLoader );
然后,您的组件将如下所示:

define(['text!settings.html'],
    function( htmlString) {
        'use strict';

       function SettingsViewModel(params) {
           ...
       }
        // Return component definition
        return {
            viewModel: SettingsViewModel,
            template: htmlString
        };
    });
define([],
    function() {
        'use strict';

       function SettingsViewModel(params) {
           ...
       }
        // Return component definition
        return {
            viewModel: SettingsViewModel,
            template: { 
                languageUrl: 'settings.html',
                language: 'nl' // overwrite default
            }
        };
    });

最终我采用了另一种解决方案,我只是在路径中添加了一个变量:

define(['text!' + globals.bundlePath + 'settings.html']

这个变量是从会话存储中初始化的(如果找不到,则默认为get),因此当用户更改语言时,我会将其保存在会话存储中并刷新应用程序,这样页面就可以加载新语言了。

您看过i18n插件了吗?然而,这也可能是关于如何在区域设置更改后重新加载内容的有趣之处:@PabloRomeo-谢谢,不幸的是,这是一个i18n和l10n已经以某种方式实现的大型应用程序(每种语言复制html文件),因此我无法更改它以满足requireJS的要求。哦,我明白了。嗯,也许require.replace插件()可以这样改变路径,但仍然不会破坏r.js。这似乎很有希望,我一定要看看。不幸的是,replace插件只支持js,不支持HTML:(这是我的第一个想法,但这意味着我必须检查许多文件并更改它们,同时让团队知道,从现在开始,我们编写的模块有点不同,我将首先尝试Pablo的,如果它不起作用,我将采用这种方法。好吧,但我确实认为,如果您愿意,一旦语言发生变化,您将很难切换模板。)重新使用文本插件。如果你有一个自定义的模板加载程序,你也可以在该加载程序中处理模板的切换。