0

基本上问题是当我点击它最初显示的链接时,例如 2 条记录在视图中。但是当我关闭页面并再次单击链接时,它假设向我显示来自模型的更新记录,因为我正在调用控制器方法,该方法实习生返回 Json resultData。但它不像它只是将视图列表附加到自身并显示带有 4 条记录的视图。如果我重复打开窗口,它会显示 2、4、8、16 之类的记录...... :(

我的代码如下所示:

文件1.cshtml:

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

文件1.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"))

文件2.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"));
};

文件2.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 结果数据。
  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 回答
1

解决上述问题。实际上问题是我在函数中不必要的绑定 KO 代码。下面是我所做的代码更改。

    $(function () { // docuement.ready function. 
        ko.applyBindings(Section2VM, document.getElementById("Section2"));
    });
    //Define globally 
    var Section2VM= {
        List: ko.observableArray([]),
        ListCount: ko.observable()
    };

    function initSection2VM (resultData) {
        var counter = 0
        Section2VM.List([]);
        ko.utils.arrayForEach(resultData, function (entry) {
            Section2VM.List.push(entry);
            counter++;
        });
        Section2VM.ListCount(counter);
    };
于 2013-06-07T19:11:45.830 回答