【问题标题】:Composing separate module instances in Durandal在 Durandal 中组合单独的模块实例
【发布时间】:2014-06-16 19:29:57
【问题描述】:

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

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

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

提前谢谢你

【问题讨论】:

  • 你应该考虑使用小部件来处理这种事情durandaljs.com/documentation/Creating-A-Widget.html
  • 我试过但同样的问题。我正在使用它来将表单动态附加到 view.htmlwidget.create(document.getElementById("odbc-forms-" + appendClickCount()), { kind: 'odbcForm', hostname: '', db: '' });

标签: knockout.js durandal knockout-2.0


【解决方案1】:

将您的 forms/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 函数)不应该有参数。此外,将 observables 放在原型上也不是一个好主意——你会泄漏内存。如果您真的希望将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: config.hostname,而不是value: hostname

使用这种方法,您可以随着应用程序的增长构建配置模块,而无需重构每个模块。另外,你知道你不必叫它ctor,对吧?为了方便调试,给你的模块一个明确的名字,比如OdbcForm,这样你就有:

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

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

【讨论】:

    【解决方案2】:

    原型是共享的。您不应该将属性值放在原型上。属性值应该继续实例。只放函数。所有属性(observables)都应该放在“this”对象实例上。

    【讨论】:

    • 感谢您的澄清。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 2022-01-05
    相关资源
    最近更新 更多