在Durandal中组成单独的模块实例 [英] Composing separate module instances in Durandal

查看:80
本文介绍了在Durandal中组成单独的模块实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在同一模块视图中多次编写相同的表单,但是当我在一个字段中更改数据时,它会反映在每种表单上.

I am composing the same form multiple times in the same module view but when I change the data in one field it reflects on every forms.

这是一些清理后的代码.如您所见,我确保不要对要多次编写的表单使用单例模式...

Here is some cleaned up code. As you can see I made sure not to use the singleton pattern for the form I want to compose multiple times...

view.html

<button data-bind="click: append">Append</button>

<div data-bind="foreach: odbcForms">
    <div data-bind="compose: { model: $data, activationData: settings }"></div>
</div>

viewmodel.js

define(['knockout', 'forms/odbc'], function ( ko, odbcForm) {
    var odbcForms = ko.observableArray()

    var append = function () {
        odbcForms.push(new odbcForm({ hostname: 'v1', db: 'v2' }));
    };

    return {
        odbcForms: odbcForms,
        append: append
    }
}

forms/odbc.html

<div>
    <form class="form-horizontal" role="form">
        <fieldset>
            <div class="form-group" data-bind="validationElement: hostname">
                <label for="hostname" class="col-sm-2 control-label">ODBC Link Name</label>

                <div class="col-xs-4">
                    <input data-bind="value: hostname" type="text" class="form-control" id="hostname">
                </div>
            </div>

            <div class="form-group" data-bind="validationElement: db">
                <label for="db" class="col-sm-2 control-label">Database</label>

                <div class="col-xs-4">
                    <input data-bind="value: db" type="text" class="form-control" id="db">
                </div>
            </div>
        </fieldset>
    </form>
</div>

forms/odbc.js

define(['knockout'], function(ko) {
    var ctor = function (settings) {
        this.settings = settings;
    };

    ctor.prototype = {
        constructor: ctor,

        activate: function (settings) {
            this.hostname(this.settings.hostname);
            this.db(this.settings.db);
        },

        hostname: ko.observable().extend({
            required: true,
            minLength: 2
        }),

        db: ko.observable().extend({
            required: true,
            minLength: 2
        }),
    };

    return ctor;
}

提前谢谢

推荐答案

将您的form/odbc.js更改为以下内容:

Change your forms/odbc.js to the following:

define(['knockout'], function(ko) {
    var ctor = function () {
        this.settings = settings;
        this.hostname = ko.observable().extend({
            required: true,
            minLength: 2
        };
        this.db = ko.observable().extend({
            required: true,
            minLength: 2
        });
    };        

    ctor.prototype.activate = function (settings) {
        this.hostname(this.settings.hostname);
        this.db(this.settings.db);
    };

    return ctor;
});

您的做法可能会使Durandal感到困惑.在forms/odbc模块中的其他问题中,构造函数上不应有任何参数(ctor函数).同样,将可观察对象放置在原型上也不是一个好主意,否则会泄漏内存.如果您真的希望将hostnamedb建立为某种全局变量,请创建一个单独的config模块,使其成为单例,然后使用RequireJS注入它,如下所示:

It might be that Durandal is confused by your approach. Among other issues in your forms/odbc module, there should be no argument on the constructor (ctor function). Also, it is not a good idea to place observables on a prototype--you'll leak memory. If you really wish to establish hostname and db as some sort of global, create a separate config module, make it a singleton, and then inject it using RequireJS, like so:

define('config', ['knockout'], function(ko) {
    var 
        hostname = ko.observable(),
        db = ko.observable();

    return {
        hostname: hostname,
        db: db
    }
});

然后将odbc.js更改为以下内容:

Then change your odbc.js to the following:

define(['knockout', 'config'], function(ko, config) {
    var ctor = function (settings) {
        this.settings = null;     
        this.config = null;
    };        

    ctor.prototype.activate = function (settings) {
        this.settings = settings;
        this.config = config;
        config.hostname(settings.hostname);
        config.db(settings.db);
    };

    return ctor;
});

您的视图将需要稍作更新:例如,您需要更改为value: config.hostname而不是value: hostname.

Your view would need to be updated slightly: Instead of value: hostname, for example, you would need to change to value: config.hostname.

使用这种方法,您可以在应用程序扩展时构建配置模块,而不必重构每个模块.另外,您知道您不必称其为ctor,对吗?为了便于调试,请为模块指定一个明确的名称,例如OdbcForm,这样您就可以:

With this approach, you can build out your config module as your application grows without having to refactor every module. Also, you do know that you don't have to call it ctor, right? In order to facilitate debugging, give your module an explicit name, say OdbcForm, so that you would have:

var OdbcForm = function()
...
return OdbcForm;

它将在调试器中显示为OdbcForm而不是ctor.

It will show up in the debugger as OdbcForm instead of ctor.

这篇关于在Durandal中组成单独的模块实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆