【问题标题】:Durandal: How to pass config data from HTML Host to ViewModel?Durandal:如何将配置数据从 HTML 主机传递到 ViewModel?
【发布时间】:2013-07-21 21:26:05
【问题描述】:

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

如何让我的视图通过 main.js、shell 将数据传递到 durandal 中的视图模型?

现在我在一个讨厌的全局变量中设置值,然后在我的 index.phtml 中的视图模型中引用该全局变量:

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

在直接 KO 应用程序中,我会直接将其传递给 KO 视图模型构造函数(或设置可观察属性)。

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 感谢详细的回复,如果不是我的条件,它会很好用。但是我无法通过 ajax 从服务器“获取”我的配置,因为该配置是服务器 URL 本身。该应用程序托管在各种主机/路径/子路径上,因此了解服务根 url 的唯一可靠方法是在服务器本身上。这就是为什么 ajax 技术对我不起作用的原因。如果可能的话,我想避免将发现逻辑放在 JS 中。
    • 您编辑的回复有点骇人听闻,但比我的超级全球骇客要少得多。您不能在主机页面中进行定义吗?
    • 在典型情况下,require.js 还不会被加载,所以define 将是undefined。您可以尝试在标题中加载 require.js,然后 `define('appconfig', [], function() { return contentRoot = "=$this->contentRoot?>"; }) 最后加载 main. js.
    • @RainerAtSpirit:这可能行得通。不过,不确定对 SPA 会有什么影响。 ChrisDaMour:是的,这有点老套,但你要么必须这样做,要么使用 Rainer 的建议。
    猜你喜欢
    • 2022-01-21
    • 1970-01-01
    • 2022-11-25
    • 2018-12-25
    • 1970-01-01
    • 2021-01-04
    • 2020-08-03
    • 2020-02-23
    • 2020-08-28
    相关资源
    最近更新 更多