构成在迪朗达尔单独模块实例(Composing separate module instances

2019-10-20 01:00发布

我多次组成相同形式在相同的模块视图,但是当我改变一个字段中的数据反映在每一个形式。

下面是一些清理代码。 正如你可以看到我确信不使用Singleton模式,因为我要撰写多次形式...

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

表格/ 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>

表格/ 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;
}

先感谢您

Answer 1:

改变你的表格/ odbc.js以下几点:

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

这可能是迪朗达尔是由你的做法感到困惑。 在你的表格/ ODBC模块中的其他问题,应该在构造(没有参数的ctor功能)。 而且,不要对原型观测一个好主意 - you'll泄漏内存。 如果你真的想建立hostnamedb的某种全球性的,创建一个单独的config模块,使之成为单身,然后使用RequireJS,像这样注入它:

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

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

然后改变你的odbc.js以下几点:

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: hostname ,例如,你需要改变value: config.hostname

通过这种方法,你可以为你的应用程序的增长,而无需重构每个模块打造出你的配置模块。 另外,你知道,你不必把它称为ctor ,对不对? 为了调试方便,给你的模块一个明确的名称,说OdbcForm ,这样你就会有:

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

它会在调试器显示OdbcForm而不是ctor



Answer 2:

原型是共享的。 你不应该放在原型属性值。 属性值应该去的情况。 只放功能。 所有属性(观测)应该对“此”对象实例。



文章来源: Composing separate module instances in Durandal