1

基本的にシーケンシャルスプレッドシートとして機能するコンポーネントを備えたKnockoutJSを使用してアプリケーションを構築しています。異なる行で、ユーザーは変数を定義するか、それらを使用して値を表すことができます。

だから例えば

x =2 
x  //2
x = 4
x  //4

私はこれを、新しい行を追加し続けるという単純なケースで機能させています。各行の出力関数は、変数が以前に定義されたかどうかを確認するために逆方向にチェックおよび反復します。最初の例を使用している場合は、それを見つけて値として設定します。これは、最初に行を定義するときに機能し、前の行が変更された後に行を編集するときにも機能します。

ただし、その変数の以前の定義が変更、削除、または追加された場合は、変数を更新したいと思います。その動作は現在存在しません。マップを使用して変数を追跡する独自のカスタム依存関係処理コードを追加しようとしましたが、パフォーマンスに悪影響を及ぼしました。これを解決するためにKnockoutsの依存関係管理を利用したいのですが、そのための最善の方法がわかりません。これが私のコード構造の簡単な要約です。必要に応じてさらに詳細を追加したいと思います。

calcFrameworkマップにバインドするビューモデルオブジェクトです。これは、Lines、varMap、およびその他の無関係なプロパティと関数の監視可能なリストで構成されています

Lineカスタムオブジェクトです。関連するコードは以下のとおりです

var Line = function (linenum,currline) {
    var self = this;
    self.varMap = {};
    self.input = ko.observable("");
    self.linenum = ko.observable(linenum); 

    self.lnOutput = ko.computed({
        read:function(){
           return outputFunction(self,self.input());
        },
        write:function(){},
        owner:self
    });
};

function  outputFunction(self,input) {
    try{
        var out = EQParser.parse(input,10,self);
        return  out.toString();
    }
    catch(ex){
        //error handling
    }
}

Line.prototype.getVar = function (varName, notCurrentLine) {
    if(typeof varName === "undefined"){
        return null;
    }
    //Actually don't want ones set in the current varMap, only past lines
    if(varName in this.varMap && notCurrentLine){
        return this.varMap[varName];
    }

    if (this.linenum() > 0) {
        var nextLine = calcFramework.lines()[this.linenum() - 1];
        return nextLine.getVar(varName,true);
    } else {
        //eventually go to global
        return calcFramework.varMap[varName];
    }
};

Line.prototype.setVar = function(varName,value){
    this.varMap[varName] = value;
};

SetVarとgetVarはeqParserに渡され、eqParserは式の値を取得し、変数が参照されている場合は必要に応じてこれらの関数を呼び出します。したがって、変数値は関数に明示的に渡されないため、ノックアウトはそれを依存関係とは見なしません。しかし、毎回リストをトラバースせずに、変数をパラメーターとして渡す方法がわかりません。

したがって、私の質問は、この設定を前提として、良好なパフォーマンスを維持しながら、変数の割り当て(および/または新しい割り当て)への変更を追跡し、その変数を参照する行を更新するための最良の方法は何ですか?

私の質問は長いことを認識しており、不要な詳細をすべて削除しようとしました。しばらくお待ちいただきますようお願いいたします。

4

1 に答える 1

1

PeterHigginsのPubSubjqueryプラグインのようなものを使用して、パブリッシュ/サブスクライブモデルを使用したくなるでしょう。

アプリ全体は、可変定義を持つイベントを公開している行をサブスクライブ/リッスンします。これにより、変数名が値とともに標準のjavascriptハッシュテーブルに格納されます。変数が見つかったイベントが行によって公開されると、アプリはすべての既知の変数をチェックし、それが既存の変数値への変更であることがわかった場合、変数が変更されたイベントを公開します。すべての回線がそのイベントをサブスクライブします。次に、その名前に一致する変数があるかどうかを確認し、それに応じて値を更新できます。

これが私が何を意味するのかをあなたに理解させるためのいくつかのテストされていないコードです:

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

    self.variables = {};
    $.subscribe('/variableAssigned', function (key, value)
        {
            // I think that this is the best way of checking that there is a variable
            // in the object
            if(self.variables.hasOwnProperty(key))
            {
                if(self.variables[key] !== value)
                {
                    $.publish('/variableChanged', [ key, value ]);
                }
            }
        });
}

Lineオブジェクト内:

$.subscribe('/variableChanged', function (key, value)
    {
        // loop through varMap and see if any of them need updating.
    });
于 2013-01-28T09:58:29.320 に答える