2012-12-10 10 views
8

私のビューモデルが非常に大きくなり始めたので、複数のファイルに分割することにしました。私はすでにさまざまなアプローチを試みてきましたが、何も動いていませんでした。私は複数のファイル間でプライベート関数と観測可能なパラメータにアクセスする必要がノックアウトビューモデルを複数のファイルに分割する

namespace.model = function(constructorParam) { 
    var self = this; 

    self.param1 = ko.observable(constructorParam.param1); 
    self.param2 = ko.observable(privateFunction(constructorParam)); 

    self.clickEvent = function() { 
     // do something with params 
     // call some private funcitons 
     privateFunction2(self.param2); 
    }; 

    function privateFunction(param) { 
     // do some stuff 
    } 

    function privateFunction2(param) { 
     // do some stuff 
    } 
}; 

マイビューモデルは次のようになります。最終的なモデルは次のようになります:

// file 1 
// contains constructor and param initialization + many common private helper funcitons 
namespace.model = function(constructorParam) { 
    var self = this; 

    self.param1 = ko.observable(constructorParam.param1); 
    self.param2 = ko.observable(privateFunction(constructorParam)); 

    function privateFunction(param) { 
     // do some stuff 
    } 

    function privateFunction2(param) { 
     // do some stuff 
    } 
}; 

// file 2 
// contains event hendlers 
self.clickEvent = function() { 
    // i need to acces properties from namespace.model 
    self.param1 

    // call some private funcitons 
    privateFunction2(self.param2); 
}; 

// view model initialization 
ko.applyBindings(new namespace.model(initValues)); 

ノックアウトでこれを実現することは可能でしょうか? ありがとう

答えて

5

RequireJSのようなライブラリを見て、viewmodelを別の 'モジュール'に分割してメインのViewModelに読み込むことができます。

KnockoutウェブサイトにRequireJS with Knockoutを使用した非常に簡単な例がいくつかあります。

John Papaがシングルページアプリケーションを構築するのに本当に役立つ記事をご覧ください。here

+2

RequireJSなしでも実行できますか? –

+0

@MajoB、はい、これはRequireJSなしで行うことができます。しかし、RequireJSのようなライブラリを使用する利点の1つは、依存関係を明示的にすることです。ここで説明するように、モデルから部品を構成する場合は非常に便利です。 – kiprainey

5

最後に、私はそれを行う方法を見つけましたhere。ここで は完全な例である:

<div> 
    Name: <input data-bind="value: name" type="text" /> <br /> 
    Surname: <input data-bind="value: surname" type="text" /><br /> 
    Fullname: <span data-bind="text: fullName"></span><br /> 
    <button data-bind="click: showName">Show Name</button> 
</div> 

<script> 

    Function.prototype.computed = function() { 
     this.isComputed = true; 
     return this; 
    }; 

    Object.prototype.makeComputeds = function() { 
     for (var prop in this) { 
      if (this[prop] && this[prop].isComputed) { 
       this[prop] = ko.computed(this[prop], this, { deferEvaluation: true }); 
      } 
     } 
    }; 
    // file 1 
    var namespace = namespace || {}; 

    namespace.model = function (params) 
    { 
     var self = this; 

     self.name = ko.observable(params.name); 
     self.surname = ko.observable(params.surname); 

     self.makeComputeds(); 
    }; 

    // file 2 
    (function() { 
     function showFullName(fullName) { 
      alert(fullName); 
     } 

     ko.utils.extend(namespace.model.prototype, { 

      showName: function() { 
       showFullName(this.fullName()); 
      }, 
      // computed observable 
      fullName: function() { 
       return this.name() + " " + this.surname(); 
      }.computed() 

     }); 

    })(); 

    ko.applyBindings(new namespace.model({ name: "My Name", surname: "My Surname" })); 

</script> 

EDIT

RequireJSとKnockoutJSを兼ね備えDurandalというプロジェクトがあります。 KnockoutJSのSPAアーキテクチャのベストプラクティスに興味があるかどうかを見ておく価値があります。

関連する問題