2014-04-30 54 views
1

我在同一模塊視圖中多次編寫相同的表單,但是當我在一個字段中更改數據時,它會反映在每個表單上。在Durandal中編寫單獨的模塊實例

這是一些清理的代碼。正如你可以看到我確信不使用,因爲我要撰寫多次形式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; 
} 

預先感謝您

+0

你應該看看使用這種東西的小部件http://durandaljs.com/documentation/Creating-A-Widget.html –

+0

我試過但同樣的問題。我正在使用它來動態追加表單到** view.html **: 'widget.create(document。getElementById(「odbc-forms-」+ appendClickCount()),{kind:'odbcForm',hostname:'',db:''});' – romseguy

回答

2

更改表單/ 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; 
}); 

這可能是迪朗達爾是被你的方法困惑。在你的forms/odbc模塊中的其他問題中,構造函數應該沒有參數(ctor函數)。另外,將觀察點放在原型上不是一個好主意 - 你會泄漏內存。如果你真的想建立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

+0

非常有幫助,現在可以正常工作。謝謝! – romseguy

1

原型是共享的。你不應該把屬性值放在原型上。屬性值應該在實例上。只放置函數。所有屬性(observable)都應該放在「this」對象實例上。

+0

謝謝你的澄清。 – romseguy