删除后,Knockout视图不会从视图中删除项目

时间:2014-11-07 19:41:58

标签: javascript knockout.js asp.net-mvc-5 typescript

我有这段代码可以从页面上显示的考试列表中成功删除考试,但该页面仍会显示已删除的考试。您必须手动刷新页面才能更新视图。我们在其他页面上使用simlar模式并且它正常工作。我不明白为什么它在这个页面上不起作用。

 // Used to handle the click event for Delete
    remove = (exam: Models.Exam) => {
        $("#loadingScreen").css("display", "block");
        var examService = new Services.ExamService();

        examService.remove(exam.examId()).then(() => {
            examService.getByFid().then((examinations: Array<Models.Exam>) => {


                this.exams(examinations);

                this.template("mainTemplate");
            });
        }).fail((error: any) => {
                // Add this error to errors
                this.errors([error]);
                window.scrollTo(0, 0);
            }).fin(() => {
                $("#loadingScreen").css("display", "none");
            });
    }

这是显示考试列表的UI代码

    <div class="section module">
        <!-- ko if: exams().length > 0 -->
        <!-- ko foreach: exams.sort(function(a,b){return a.mostRecentDateTaken() > b.mostRecentDateTaken() ? 1:-1}) -->
        <div class="addremove_section bubbled">
            <a class="button open_review" data-bind="click: $root.edit">Edit</a>
            <a class="button open_review" data-bind="click: $root.remove">Delete</a>
            <div class="titleblock">
                <h4 data-bind="text: 'Exam Name: ' + examTypeLookup().examTypeName()"></h4>
                <div data-bind="if:examEntityLookup()!=null">
                    <div data-bind=" text: 'Reporting Entity: ' + examEntityLookup().description()"></div>
                </div>
                <div data-bind="text: 'Most recent date taken: ' +  $root.formatDate(mostRecentDateTaken())"></div>
                <div data-bind="text: 'Number of attempts: ' + numberOfAttempts()"></div>
                <div data-bind="text: 'Pass/Fail Status: ' + $root.PassFailEnum(passFailId())"></div>
            </div>
            <div class="clearfix"></div>
        </div>
        <!-- /ko -->
        <!-- /ko -->
        <!-- ko if: exams().length == 0 -->
        <div class="addremove_section bubbled">
            <div class="titleblock">
                <div>No Exams Have Been Entered.</div>
            </div>
        </div>
        <!-- /ko -->
    </div>

编辑:我发现如果我在视图中删除此行的排序

<!-- ko foreach: exams.sort(function(a,b){return a.mostRecentDateTaken() > b.mostRecentDateTaken() ? 1:-1}) -->

<!-- ko foreach: exams -->

它有效!唯一的问题是我需要对数据进行排序。

2 个答案:

答案 0 :(得分:0)

我从视图中删除了排序并在服务中进行了排序。不确定为什么我不能在视图中排序。我认为这是一个knockout.js错误。

<!-- ko foreach: exams -->


        [HttpGet]
        [Route("api/exam")]
        public IEnumerable<TDto> GetApplicantExams()
        {

                var dtos = GetCollection(() => _examService.GetApplicantExams(UserContext.Fid).OrderBy(e => e.DateTaken));
                return dtos.ForEach(t => AddItems(t));

        }

答案 1 :(得分:0)

这不是Knockout中的错误。由于排序调用(正如你所做的那样)不受计算/从属可观察量的控制,因此无法触发它。您基本上已经破坏了UI(或者更具技术性,bindingHandler)和KO用于跟踪更改的ko.observable之间的连接。

我在这里工作过很多次,我使用的一般模式是这样的:

var viewmodel = {
    listOfObjects:ko.observableArray(),
    deleteFromList:deleteFromList,
    addToList:addToList,
}

//in your HTML,  you'll do a foreach: listOfSortedObjects (instead of listOfObjects)
viewmodel.listOfSortedObjects = ko.computed(function(){
    //Since this is *inside* the change tracking ecosystem, this sort will be called as you would expect
    return viewmodel.listOfObjects().sort(yourSortingFunction);
});

//Since you cannot edit a (normal) computed,  you need to do your work on the original array as below.

function deleteFromList(item){
    viewmodel.listOfObjects.remove(item);//Changing this array will trigger the sorted computed to update, which will update your UI
}
function addToList(item){
    viewmodel.listOfObjects.push(item);
}