Durandal:如何将配置数据从HTML主机传递到ViewModel?

时间:2013-07-23 00:17:08

标签: zend-framework mvvm knockout.js viewmodel durandal

我正在使用Zend生成我的主视图主机。因此,它是唯一在服务器端解析的HTML。我的服务器知道我想要一直传递给我的一个viewmodel的配置参数。我不希望viewmodel通过ajax请求此数据。

如何让我的视图通过main.js传递数据,通过shell传递到durandal中的viewmodel?

现在我正在设置一个讨厌的全局值,然后在我的index.phtml中的viewmodel中引用该全局:

    <script>
        //This sucks, but i don't know how to pass stuff down into Durandal yet...
        //
        window.ServiceRoot = "<?=$this->contentRoot?>";
    </script>

在直接的KO应用程序中,我将它传递给KO viewmodel构造函数(或设置一个observable属性)。

从技术上讲,我正在使用durandal 2.0预发行,但我不认为这很重要。我想我需要通过require.js脚本标签传递参数,就像我主要的params。

1 个答案:

答案 0 :(得分:2)

我建议你添加一个config.js模块来保存你的“配置”数据。添加一个初始化函数以从服务器获取配置数据并对其进行缓存。

然后......在你的shell.js的activate函数中,在绑定你的视图之前初始化配置。

然后,您可以在所有视图模型中要求配置模块,它只会返回缓存的数据。

<强> config.js

define(['dataaccessmodule'], function (dataaccessmodule) {
    var config =
        {
            serviceRoot: null,
            init: init
        };

    var init= function()
    {
        // get config from server and set serviceRoot;
        // return a promise
    };
    return config;
});

<强> shell.js

define([... your required modules..., 'config'],
    function (..., config) {

        function activate() {
            return config.init().then(boot);
        };
        function boot() {
            // set up routing etc...

            // activate the required route
            return router.activate('home');
        };
});

<强> someViewModel.js

define([... your required modules..., 'config'],
    function (..., config) {
        var someViewModel =
        {
            serviceRoot: config.serviceRoot
        };

        return someViewModel;
    });

我知道你说你不想通过ajax加载数据,但是使用这种方法,你只需加载一次并重新使用它。如果需要,您还可以加载额外的配置。这使用单一责任原则很好地分离了代码。

修改

如果您确实需要在渲染页面中执行此操作,您可以按照以下方式执行操作:

<script>
var myapp = myapp || {};

myapp.config= (function() {

    var contentRoot = "<?=$this->contentRoot?>";
    return {
        contentRoot: contentRoot
    };
})();
</script>

然后,在main.js中,在定义主模块之前,您可以使用以下方法将其短路:

define('appconfig', [], function () { return myapp.config; });

然后,您可以像往常一样在viewmodel中要求appconfig模块,并使用appconfig.contentRoot访问contentRoot。