2013-05-15 69 views
0

我有以下控制器:knockout.js AJAX结果在ASP.Net MVC

 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个项目中的每一个。我需要以某种方式清除我的viewmodel,并在每次点击搜索按钮时重新填充。

回答

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查找。而且不需要多次绑定页面级视图模型。

+0

哇。我认为这也是答案,因为正如你所说的,它更接近于面向对象的原则,而且它非常完美。我将使用此方法,因为viewmodel将更接近地匹配视图。谢谢! – steveareeno

+0

顺便说一句,我喜欢你投掷的“搜索”消息。 – steveareeno

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); 
     } 
    }); 
} 
+0

原始代码的问题在于,每次执行搜索时都会调用ko.applyBindings。出于这个原因,这个解决方案不会解决问题。 – RodneyTrotter

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); 
    }); 
}) 
+0

这样做!谢谢Rodney! – steveareeno