0

Controlビューモデルの 1 つに、後でビューにバインドするオブジェクトを作成する関数があります。

(コードは私のビューモデルを再現しているだけなので、不完全であるか、いくつかの間違いを含んでいる可能性があります。詳細が必要な場合は、以下のコメントで質問してください。例は durandaljs フレームワークを参照しているため、JsFiddle を提供できません。)

function Control ( value ) {
    var self = this;
    self.param = value;
    self.param1 = ko.observable(value.text());
    self.param2 = ko.computed(function() {
        read: function(){
            return getString(self.param.text()).StringValue();
        },
        write: function(newValue){
            stringsArray.push(
                {StringID: ko.observable(-1), StringValue: ko.observable(newValue)});
            self.param.text(-1);
        },
        owner: self
    });
    self.param3 = ko.computed(function() {
        return self.param2() + ' something_else';
    });
    self.param1.subscribe(function( newValue ) {
        if ( newValue ) {
            self.param3(newValue + 'text');
        }
    });

}

var controls = ko.observableArray([
    new Control({id: 1, text: ko.observable(2)}),
    new Control({id: 2, text: ko.observable(4)}),
    new Control({id: 2, text: ko.observable(1)})
]);

var stringsArray = ko.observableArray([
    {StringID: ko.observable(1), StringValue: ko.observable('aaa')},
    {StringID: ko.observable(2), StringValue: ko.observable('bbb')}
    {StringID: ko.observable(3), StringValue: ko.observable('ccc')}
    {StringID: ko.observable(4), StringValue: ko.observable('ddd')}
    {StringID: ko.observable(5), StringValue: ko.observable('eee')}
    {StringID: ko.observable(6), StringValue: ko.observable('fff')}
]); // data retrieved from the database

var deactivate = function() {
    controls.removeAll();
    stringsArray.removeAll();
};

var vm = {
    deactivate: deactivate,
    controls: controls,
    stringsArray: stringsArray
};
return vm;

function getString ( stringID ) {
    for ( var i = 0; i < stringsArray().length; i++ ) {
        if ( stringsArray()[i].StringID() === stringID ) {
            return stringsArray()[i];
        }
    }
    return undefined;
}

私の問題は、関数から作成されたオブジェクトがグローバルにスコープされているため、ビューモデルを非アクティブ化してもメモリ内に存在することです。

function Control(value)作成するオブジェクトがviewmodelスコープを持つように、どのように書き直す必要がありますか。deactivateビューモデルがアクティブな場合にのみ存在し、メソッドのobservableArrayから削除すると破棄されますか?

4

2 に答える 2

0

どうやら私の問題はko.computed、オブジェクトに含まれていることでした。ビューモデルを非アクティブ化したときに、計算されたものは削除されませんでした。これは、それらが依存している一部の外部データがまだメモリ内にあったためです。

この投稿でそれについて見つけました:https://groups.google.com/d/msg/knockoutjs/4HV_PgcBNXA/ozoyXlygJHwJ

非アクティブ化機能で手動で破棄した後ko.computed、問題はなくなりました。

于 2013-10-16T10:52:25.553 に答える
0

興味深い例ですが、上記のコードが実際に実行していることを反映しているかどうか、またはコピー/貼り付けの問題であるかどうかはわかりません。

デバッグするために、 http: //dfiddle.github.io/dFiddle-2.0/#extras/scope で dFiddle を立ち上げました。自由にフォークして変更してください。

現在、ビューから離れると、Durandal のライブ サイクル イベントdeactivateがトリガーされ、 とremoveAllからのエントリが発生しますが、少なくともビュー モデルがシングルトンを返し、cacheViews が true に設定されている場合は、ノックアウト observableArrays がメモリに残ります。stringArraycontrols

私はおそらくvmをコンストラクター関数に変換し、その上でコントロールを独自のモジュールに移動しますが、もちろん、正確な要件を知らなくても、それは単なる直感です。

以下に沿って何かを始める必要があります。

モデルを見る

define(['durandal/system', 'jquery', 'knockout', './control'], function( system, $, ko, Control ) {
    "use strict";

    var vm = function() {
        this.controls = ko.observableArray([
            new Control('value1'),
            new Control('value2'),
            new Control('value2')
        ]);
    };

    vm.prototype.deactivate = function() {
        this.controls.removeAll();
    };

    return vm;
});

制御モジュール

define(['knockout'], function(  ko ) {
    "use strict";

    function Control ( value ) {
        this.param = value;
        this.param1 = ko.observable(value.text);
        this.param2 = ko.computed(function() {
            //translate self.param.StringID with data from another
            //an observableArray containing data retrieved from the server
            //return getString(this.param.StringID()).StringValue();
            return 'Computed' + this.param.id;
        // ko.computed takes a context parameter
        }, this);
        this.param3 = ko.computed(function() {
            return this.param2() + 'something_else';
        }, this);
        this.param1.subscribe(function( newValue ) {
            if ( newValue ) {
                this.param3(newValue + 'text');
            }
        });
    }

    var stringsArray = ko.observableArray([]); // data retrieved from the database

    return Control;

    function getString ( stringID ) {
        for ( var i = 0; i < stringsArray().length; i++ ) {
            if ( stringsArray()[i].StringID === stringID ) {
                return stringsArray()[i];
            }
        }
        return undefined;
    }

});

http://dfiddle.github.io/dFiddle-2.0/#extras/scope/ctorで利用可能なライブ バージョン

于 2013-10-15T10:22:04.880 に答える