3

私は大規模なWebアプリケーションに取り組んでいますが、ノックアウトとMVCを使用して適切に設計する際に問題が発生しています。

現在、現在ログインしているユーザーに関する基本データを含むすべてのビューに渡すベースビューモデルがあります

//Example Code
public class BaseViewModel {
    public String FullName;
    public String Email;

    //A bunch of other similar values
}

次に、BaseViewModelクラスを継承するサイトの各ページ(つまり、プロファイル)に固有のビューモデルがあります。

//profile.cshtml
public class UserProfileViewModel : BaseViewModel {
    public String Address;
    public String PhoneNumber;

    //Other similar values
}

//entity.cshtml
public class UserEntityViewModel : BaseViewModel {
    public String EntityValue;
    public Int32 EntityNumber;

    //Other similar values
}

ノックアウトオブザーバブルを使用してJavaScriptでデータモデル全体を再定義し、MVCモデルにある任意のタイプのオブジェクトを作成できるようにしました。次に、JavaScriptで定義されたいくつかのビューモデルがあります。これらは、ロード、作成、編集、削除機能を可能にするために、基本的にMVCビューモデルと同じです。

これは、たとえばプロファイルページから新しいエンティティを作成したい場合にうまく機能することがわかりました。ビューモデルの新しいインスタンスを作成し、それを新しいjqueryダイアログにバインドできます。[OK]ボタンをクリックすると、エンティティを保存または作成するイベントをノックアウトビューモデルで呼び出すことができます。

このアーキテクチャは、特定のページにデータをロードしたい場合(つまり、ノックアウトデータモデルを使用してプロファイルページにデータを入力したい場合)にはあまり機能しません。現在表示しているページを特定し、特定のビューモデルをそのページにバインドする必要があるという問題が発生しました。次のコードはあまりエレガントではないと思います。

$(function() {
    if ($('.tweak-list').length) {
        var id = $('.tweak-list').attr('data-songid');
        var vm = new my.tweaksviewmodel({ songid: id });
        ko.applyBindings(vm);
    }
});

誰かが私がこれをどのように設計すべきかについて何かアドバイスがありますか?JavaScriptでBaseViewModelを作成し、ノックアウトマッピングプラグインhttp://knockoutjs.com/documentation/plugins-mapping.htmlを使用して、さまざまなデータモデルを自動的に作成するのが最善だと思います。とはいえ、適切なデータをロードできるように、モデルがバインドされているページを判別するという問題は実際には解決されません。

編集1

このアーキテクチャには、ビューモデルを各モーダルに再バインドする必要があるため、モーダルポップアップを使用してデータを追加することを利用できないという制限もあります。

誰かアイデアはありますか?

4

1 に答える 1

4

次のように設計することをお勧めします。

ページごとに特定のKnockOutViewModelを使用して異なるJavaScriptモジュールを作成します。

var app = app || {};
app.pages = app.pages || {};

app.pages.userProfile = (function () {

    function UserProfileViewModel() {
        //view model specific code
    };

    function init() {
        ko.applyBindings(new UserProfileViewModel());
    };

    return {
        init: init
    };
}());

かみそりビューで使用するJSモジュールを指定します。

@model dynamic

@{
    ViewBag.CurrentPageJsHandler = "app.pages.userProfile";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<p>Page specific content</p>

ページ固有のモジュール初期化コードをレイアウトファイルに追加します。

<html>
<body>   
    <div id="content">
        @RenderBody()
    </div>      
    @if (@ViewBag.CurrentPageJsHandler != null)
    {
        <script>
            $(function() {
                app.currentPage = @ViewBag.CurrentPageJsHandler;
                app.currentPage.init();
            });
        </script>
    }    
</body>
</html>

このようにして、すべてのページ関連コードを異なるモジュールにカプセル化できます。各JSモジュールには一意の名前があるため、それらすべてをバインドしてレイアウトに含めることができます。

于 2013-03-02T03:31:22.787 に答える