0

基本的に問題は、最初に表示されるリンクをクリックしたときです。たとえば、ビューに2つのレコードが表示されます。しかし、ページを閉じてリンクをもう一度クリックすると、モデルから更新されたレコードが表示されると思われます。これは、インターンがJson resultDataを返すコントローラーメソッドを呼び出しているためです。ビューリストをそれ自体に追加し、4つのレコードでビューを表示するだけのようには機能しません。ウィンドウを繰り返し開くと、2,4,8,16....のようなレコードが表示されます:(

私のコードは以下のようなものです:

File1.cshtml :

<div id="Section1">
    <div>
        <span>
            <a href="javascript:void(0);" data-bind="click: OnClick">Click here</a>
        </span>
    </div>
</div>

File1.js :

var Section1VM = {
    OnClick: function () {
        $.ajax({
            type: 'POST',
            url: '/controller/View/',
            success: function (resultData) {
                initSection2VM(resultData);  function declared in File2.js
            },
            dataType: 'json'
        });
    }
};
Ko.applybinding (Section1VM , document.getElementById("Section1"))

File2.js

function initSection2VM(resultData) {
    var counter = 0
    var Section2VM = {
        List: ko.observableArray([]),
        ListCount:ko.observable()
    };
    Section2VM.List([]);
    ko.utils.arrayForEach(resultData, function (entry) {
        Section2VM.List.push(entry);
        counter++;
    });
    Section2VM.ListCount(counter);
    ko.applyBindings(Section2VM , document.getElementById("Section2"));
};

File2.cshtml

<div class="whiteContent" id="Section2">
    <tbody data-bind="foreach: List()">
        <tr>
            <td><span data-bind="text: SomeDate"></span></td>
            <td><span><a href="#" data-bind="attr: { href: SomeLink }, text: SomeNumber">   
            </a></span></td>
        </tr>
    </tbody>
</div>

コードの説明:

  1. 「ここをクリック」リンクをクリックすると、File1.js にある「OnClick」が呼び出されます。
  2. 「OnClick」は、コントローラーから更新されたリストを取得するための ajax 呼び出しを提供します。コントローラーは Json の結果を関数に返します。
  3. 「OnClick」が成功すると、initSection2VM(resultData) が呼び出されます。これは File2.js で宣言され、Json resultdata を渡します。
  4. resultData を Section2VM.List にプッシュし、次に ko.applyBindings(Section2VM , document.getElementById("Section2")); にプッシュします。
  5. MeesageCenterPopUpSection が file2.cshtml に読み込まれています
4

2 に答える 2

1

問題は、呼び出しko.applyBindings回数が多すぎることです。このメソッドが呼び出されると、Observable オブジェクトがそれを表す DOM ノードにリンクされます。そして、この Observable オブジェクトが更新されるたびに、その DOM 表現も更新されますobservable。結局のところ、これが意味することです。ko.applyBindings表現を更新するための呼び出しは間違っています。場合によっては Knockout が状況自体を修正することもありますが、それ以外の場合はどうすることもできません。

理論から実践まで、問題を解決する最も簡単な方法は次のとおりです。

var initSection2VM = (function() {
    var counter = 0;
    var Section2VM = {
        List: ko.observableArray([]),
        ListCount:ko.observable()
    };
    ko.applyBindings(Section2VM, document.getElementById("Section2"));    
    return function(resultData) {
        Section2VM.List([]);
        ko.utils.arrayForEach(resultData, function (entry) {
            Section2VM.List.push(entry);
            counter++;
        });
        Section2VM.ListCount(counter);
    }
})();

ここではSection2VM、定義をローカライズし、すぐに呼び出しapplyBindingsました。結果として得られる関数はそれを操作できますが、外部の世界には見えません。

これが実際に動作していることを示す簡単なデモです。


別のアプローチは、最初の呼び出しの後に関数自体を書き直すことです。

function initSection2VM(resultData) {
    var counter = 0;
    var Section2VM = {
        List: ko.observableArray([]),
        ListCount:ko.observable()
    };
    ko.applyBindings(Section2VM, document.getElementById("Section2"));
    initSection2VM = function(resultData) {
        Section2VM.List([]);
        ko.utils.arrayForEach(resultData, function (entry) {
            Section2VM.List.push(entry);
            counter++;
        });
        Section2VM.ListCount(counter);
    };
    initSection2VM(resultData);
};

デモ

于 2013-06-06T20:43:15.217 に答える