0

我有以下控制器:

        public JsonResult EquipmentSelect(string term)
    {
        var equipmentSearchViewModel = new EquipmentSearchViewModel
        {
            EquipmentList = iEquipmentRepository.FindBy(t => t.equipment_name.Contains(term)
                || t.equipment_id.Contains(term)),
        };

        var filteredEquipment = equipmentSearchViewModel.EquipmentList.ToList();
        var sortableData = filteredEquipment.AsQueryable();
        var jsonData = new
        {
            rows = (
                     from m in filteredEquipment
                     select new
                     {
                         equipment_id = m.equipment_id,
                         equipment_name = m.equipment_name
                     }
                  ).ToArray()
        };

        return Json(jsonData, JsonRequestBehavior.AllowGet);
    }

和下面的js文件:

$(function () {
    $('#search').click(function () {
        var searchText = $('#txtsearch').val();
        getEquipment(searchText);
    })
})

// View model declaration
var EquipmentViewModel = {
    Profiles: ko.observableArray([])
};

// Bind the equipment
bindData = function (equipment) {
    var EquipmentViewModel = {
        Profiles: ko.observableArray([])
    };
    EquipmentViewModel.Profiles(equipment);
    ko.applyBindings(EquipmentViewModel);
}

getEquipment = function (searchTerm) {
    var url = 'EquipmentSelect/Equipment';
    $.ajax({
        url: url,
        cache: false,
        contentType: 'application/json',
        data: '{"term": "' + searchTerm + '"}',
        type: "POST",
        success: function (result) {
            bindData(result.rows);
        },
        error: function (jqXHR) {
            $('#message').html(jqXHR.statusText);
        }
    });
}

最后是我的观点:

@{
    ViewBag.Title = "KnockoutExample";
}
<script src="~/Scripts/knockout-2.2.1.js"></script>
<script src="~/Scripts/knockout.mapping-latest.js"></script>
<script src="~/Scripts/koViewModel.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<h2>Knockout Example</h2>
<div>
    <fieldset>
        <legend>Search</legend>
        <span>Search For</span>
        <input type="text" name="txtsearch" id="txtsearch" />
        <input type="button" value="Submit" id="search"/>
    </fieldset>
</div>
<table id="myTable" class="table table-striped table-bordered table-condensed">
    <tr> 
        <th>Equipment ID</th>
        <th>Equipment Name</th>
    </tr>
    <tbody data-bind="foreach: Profiles">
        <tr">
            <td data-bind="text: equipment_id"></td>
            <td data-bind="text: equipment_name"></td>
        </tr>
    </tbody>
</table>
<p id="message"></p>

当我单击搜索按钮时,我会得到我想要的结果。如果我再次单击它,我会得到相同的数据,但每个原始计数都会重复。例如,如果第一次调用返回 20 个项目,则第二次单击返回 20 个项目,每一个都返回 20 个。我需要以某种方式清除我的视图模型并在每次单击搜索按钮时重新填充。

4

3 回答 3

6

通过淘汰赛,我发现更容易制作页面本身的最顶层视图模型,包括页面的所有状态和行为。

var PageViewModel = {
    Profiles: ko.observableArray([]),
    SearchTerm: '', // observable not needed, doesn't trigger any changes
    Message: ko.observable(''),
    GetEquipment: function () {
        var self = this; // Retain scope of view model
        self.Message('Searching...');
        $.ajax({
            url: 'EquipmentSelect/Equipment',
            cache: false,
            contentType: 'application/json',
            data: ko.toJSON({ term: self.SearchTerm }),
            type: "POST",
            success: function (result) {
                self.Profiles(result.rows); // Re-set entire observable array
                self.Message('');
            },
            error: function (jqXHR) {
                self.Message(jqXHR.statusText);
            }
        });
    }
}
$(function () {
    ko.applyBindings(PageViewModel);
})

然后,您不仅开始回到 JavaScript 代码中的面向对象原则,而且视图也更简单地绑定到视图模型。甚至不必定义单个 id 属性。

@{
    ViewBag.Title = "KnockoutExample";
}
<script src="@Url.Content("~/Scripts/knockout-2.2.1.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout.mapping-latest.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/koViewModel.js")" type="text/javascript"></script>
<link href="@Url.Content("~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css" />
<h2>Knockout Example</h2>
<div>
    <fieldset>
        <legend>Search</legend>
        <span>Search For</span>
        <div class="input-append">
            <input type="text" data-bind="value: SearchTerm" />
            <input type="button" value="Submit" class="btn" data-bind="click: GetEquipment" />
        </div>
    </fieldset>
</div>
<table class="table table-striped table-bordered table-condensed">
    <tr> 
        <th>Equipment ID</th>
        <th>Equipment Name</th>
    </tr>
    <tbody data-bind="foreach: Profiles">
        <tr>
            <td data-bind="text: equipment_id"></td>
            <td data-bind="text: equipment_name"></td>
        </tr>
    </tbody>
</table>
<p data-bind="text: Message"></p>

不需要 removeAll()。如果您已经在使用敲除绑定,则不需要 jQuery 样式的单击事件和 id 查找。并且无需多次绑定您的页面级视图模型。

于 2013-05-16T07:25:32.647 回答
2

您的 javascript 几乎就在那里,但需要一些小的调整:

$(function () {
    function onSearchClick() {
        var searchText = $('#txtsearch').val();
        getEquipment(searchText);
    }   

    // View model declaration
    var EquipmentViewModel = {
        Profiles: ko.observableArray([])
    };

    function getEquipment (searchTerm) {
        var url = 'EquipmentSelect/Equipment';
        $.ajax({
            url: url,
            cache: false,
            contentType: 'application/json',
            data: '{"term": "' + searchTerm + '"}',
            type: "POST",
            success: function (result) {
                EquipmentViewModel.Profiles(result.rows);
            },
            error: function (jqXHR) {
                $('#message').html(jqXHR.statusText);
            }
        });
    }

    $(document).ready(function(){       
        $('#search').click(onSearchClick);
        ko.applyBindings(EquipmentViewModel);
    });
})
于 2013-05-16T00:54:27.343 回答
0

尝试这个:

bindData.EquipmentViewModel.Profiles.removeAll() 像:

    getEquipment = function (searchTerm) {
    var url = 'EquipmentSelect/Equipment';
    bindData.EquipmentViewModel.Profiles.removeAll() 
    $.ajax({
        url: url,
        cache: false,
        contentType: 'application/json',
        data: '{"term": "' + searchTerm + '"}',
        type: "POST",
        success: function (result) {
            bindData(result.rows);
        },
        error: function (jqXHR) {
            $('#message').html(jqXHR.statusText);
        }
    });
}
于 2013-05-15T23:45:10.407 回答