3

タイトルに記載されているコンポーネントで構成されるプロジェクトの特定の部分に行き詰まっています。

私は現在、私が望むように機能する概念実証を持っています:

  • Sammy はノックアウト ビューモデルに統合されています (ノックアウト サイトのチュートリアルに従って)。
  • ビューはコントローラーによってオンデマンドで読み込まれます (そのため、アプリケーション ページですべてのビューを定義する必要はありません)。

私の現在の状況では、アプリケーションの起動時にビューモデルをインスタンス化します (インスタンス化しない場合、Sammy はルーティングを処理しません)。問題は、Sammy がビューをロードしてスワップする場所です。KO をビューにバインドするには、ko.applyBindings を呼び出す必要があります。しかし、適用を繰り返し呼び出すのは悪い習慣です。

質問ですが、オンデマンドで読み込まれるビューにバインドするにはどうすればよいですか? ビューが複数回読み込まれるとメモリリークが発生するため、 ko.applybindings を呼び出すことはできません。

問題のある ko.applyBindings を持つ VM の例を次に示します。

function serviceInfoVm() {
var self = this;

self.ObjectKey = ko.observable();
self.Service = ko.observable();

self.LoadService = function () {
    $.get('ServiceData/Detail', { serviceId: self.ObjectKey() }, function (data) {
        self.Service(data);
    });
};

$.sammy('#content', function () {
    this.get('#/service/:id', function (context) {
        var ctx = context;
        self.ObjectKey(this.params['id']);

        self.LoadService();

        $.get('Content/ServiceInfo', function (view) {
            ctx.app.swap(view);
            ko.applyBindings(self);
        });
    });

}).run();
};

この問題へのポインタや解決策を持っている人はいますか?

4

3 に答える 3

3

ビューモデルにSammyコードがあり、そのビューモデルが存在し、サブビューモデルとビューをロードしたい場合にうまく機能します。だから私はそれがあなたがやろうとしていることだと思います。参考までに...サミーコードを独自のモジュールに分離し(私はrouter.jsで私のルーターと呼んでいます)、ビューモデルとは別にナビゲーションを管理できるようにします。

しかし、コードに戻って...サブビューとサブビューモデルを設定し、sammy.get が呼び出される前にそれらに対して applybindings を使用できます。基本的に、事前にルートを登録しています。次に、sammy.get は、既にデータ バインドされている新しいビューに移動します。

于 2012-08-06T16:34:50.057 に答える
1

解決策ではなく、別のアプローチ:

ビューを動的にロードするという考えを放棄することになりました。これで、ビューは常にページに表示され、可視性は次のコードによってトリガーされます。

var app = function () {
var self = this;

self.State = ko.observable('home');

self.Home = ko.observable(new homepageVm());
self.User = ko.observable(new userInfoVm());

$.sammy(function () {

    this.get('#/', function (context) {
        self.State('home');
    });

    this.get('#/info/:username', function (context) {
        self.State('user');
        self.User().UserName(context.params['username']);
        self.User().LoadInfo();
    });

}).run();

};

そして、div の可視性は次のようにトリガーされます。

<div id="homeView" data-bind="with: Home, visible: State() === 'home'">

この方法では、アプリの起動時に ko.applyBindings を 1 回だけ呼び出す必要があります。上記のビューモデルは、シェル ページにバインドされています。

詳細はこちら

于 2012-08-07T06:56:25.980 に答える
0

返されたテンプレートの特定の要素で applyBindings を呼び出すことはオプションです。

ko.applyBindings(viewModel, htmlNode) 

テンプレートの遅延読み込みに関するこの質問も参照してください: knockout.js - テンプレートの遅延読み込み

applyBindings のドキュメントはこちら: http://knockoutjs.com/documentation/observables.html

于 2012-08-06T15:28:58.853 に答える