2013-05-15 68 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