2

私はjavascript/jqueryが初めてで、knockoutjsを学んでいます。私はこの問題で立ち往生しています。私のページには 2 つの ko バインドがあります。1 つ目は、その項目に関する詳細情報を表示するためにユーザーがクリックするリンクを作成します。そのリンクには ajax 呼び出しに渡される ID が含まれており、2 番目の ko オブザーバブルにデータが返されます。

問題は、2 番目に観測可能なデータがページ上で常に「未定義」として表示されることです。それでも、オブザーバブルが作成されるコードに console.log(data) を配置すると、データはそこにあります。同様に、Fiddler では、ajax 呼び出しによって要求された json が正常に返送されています。

これは、オブザーバブルをバインドする方法に関係していると確信していますが、いくつかの異なる方法(配列を使用する、配列を使用しないなど)を試しましたが、役に立ちませんでした。どんな助けや指針も大歓迎です。単純な問題のように思えますが、私はすべてを試しましたが、うまくいきません...

    $(document).ready(function () {

        var da = new firstViewModel();

        ko.applyBindings(da, document.getElementById('da'));


        var eq = new secondViewModel(); 
//Binding the second observable here but not using it yet as it depends on getting data from the //first (da) in order to work.

        ko.applyBindings(eq, document.getElementById('eqdetails'));  

    });

     function da(data) {
            var self = this;
            self.eqid = ko.observable(data.eqid);
            self.modelname = ko.observable(data.modelname);

        }

    function firstViewModel() {

        // Data    
        var self = this;
    self.da = ko.observableArray([]);

    self.getdetails = function (da) {

        selectedid = da.eqid();

//Call second observable when user clicks on link. 
        var eq = new secondViewModel();
        eq.geteqdetails();

    }

    };
};


     function eqview(data) {

        console.log('in eqview ' + data); //This works, but data is still undefined in html 
        var self = this;
        self.modelname = ko.observable(data.modelname);
        self.number = ko.observable(data.number);

    };

    function secondViewModel() {

        var self = this;

        self.eqviews = ko.observableArray([]);

        self.geteqdetails = function () {

            $.ajax("../Process/GetEqDetails", {
                type: "post",
                contentType: "application/json",
                data: JSON.stringify({ EqID: selectedid }),
                success: function (result) {
                    console.log('in ajax call ' + result.data);

                    var mappedequipmentview = $.map(result, function (item) { return new eqview(item) });
                    self.eqviews(mappedequipmentview);

                }
            });

        };

ページの HTML は次のとおりです。

<div id="da" class="span3">
    <table class="table table-bordered table-striped table-condensed">
        <thead>
            <tr>
                <th>Model</th>
                <th>ID</th>
            </tr>
        </thead>
        <tbody data-bind="template: { name: 'datemplate', foreach: da }">
        </tbody>
    </table>


    <script id="datemplate" type="text/html">
        <tr>
            <td><span data-bind="text: modelname"></span></td>
            <td>
                <button type="button" class="btn btn-link" data-bind="click: $root.getdetails" title="View">
                    <span data-bind="text: eqid"></span></button>
            </td>
        </tr>
    </script>
</div>


<div class="span6">

    <div class="span1">
    <table class="table table-bordered table-condensed"  id="eqdetails">
        <tbody >

            <tr>
                <td><span data-bind="text: $data.modelname "></span></td>
            </tr>
            <tr>
                <td><span data-bind="text: $data.number "></span></td>
            </tr>
        </tbody>
    </table>


    </div>



    </div>

</div>

4

1 に答える 1

0

あなたが示したコードにはいくつかのエラーがあると思います。

  • ドキュメントの準備ができたら、「secondViewModel」をインスタンス化し、バインディングを適用します。それは問題ありませんが、決して使用しません。コードの 33 行目で新しいモデルをインスタンス化しています。あなたはそれをすべきではありません。モデルにバインディングを適用したら、モデル内のデータを変更する場合は、このモデルへの参照を保持する必要があります。ノックアウトは魔法のようなものですが、それだけではありません。作成した各 secondViewModel を「eqdetails」テーブルにバインドする必要があることを認識していません。
  • コードの 62 行目で、「geteqdetails」関数のコンテキストには存在しない「selectid」変数を参照しています。それを参照できるようにするには、「selectid」をパラメーターとして「geteqdetails」関数に渡す必要があります。
  • 最後に、2 つのビュー モデルが必要かどうかはわかりません。これにより、コードの理解と維持が難しくなると思います。おそらく 1 つのビュー モデルのみを使用します。この方法では、データを更新するために secondViewModel への参照を保持する必要はありません。または、ルーティングを使用する方法もあります。
于 2013-07-18T06:16:17.323 に答える