Вот один подход.
У вас есть отдельный контроллер WebAPI для обработки доступа к данным со стороны клиента.
//Inside your CommentsApiController, for example
public IEnumerable<Comment> Get(int id)
{
var comments = _commentsService.Get(int id); //Call lower layers to get the data you need
return comments;
}
У ваших контроллеров MVC есть действия, которые возвращают PartialViewResults
.Это простое действие, которое возвращает частичное представление.
//Inside your MVC CommentsController, for example
public PartialViewResult CommentsList(int id)
{
return PartialView(id);
}
Ваше частичное представление отображает вашу разметку с нокаутирующими привязками.Мы создаем уникальный идентификатор для нашего HTML-кода, чтобы мы могли привязать нашу нокаутирующую модель представления к этому конкретному разделу страницы (избегая конфликтов с другими нокаутирующими компонентами на странице).Требуемый нами JavaScript (выбиваемые модели представления и т. Д.) Включается, создается новая ViewModel и применяются привязки выбивания.
@{
var commentsId = Model; //passed from our MVC action
var uniqueIid = System.Guid.NewGuid().ToString();
}
<section class="comments" id="@uniqueIid ">
<ul data-bind="foreach: { data: Comments, as: 'comment' }">
<li>
<span data-bind="text: comment.Author"></span>
<p data-bind="text: comment.Message"></p>
</li>
</ul>
</section>
@Scripts.Render("~/js/comments") //using MVC Bundles to include the required JS
@{
//generate the URL to our WebAPI endpoint.
var url = Url.RouteUrl("DefaultApi", new { httproute = "", controller = "Comments", id = commentsId });
}
<script type="text/javascript">
$(function() {
var commentsRepository = new CommentsRepository('@url');
var commentsViewModel = new CommentsViewModel(commentsRepository);
var commentsElement = $('#@uniqueIid')[0];
ko.applyBindings(commentsViewModel, commentsElement);
});
</script>
Внутри нашего JavaScript мы определяем наши модели отображения выбивки и т.д.
var CommentsRepository = function(url) {
var self = this;
self.url = url;
self.Get = function(callback) {
$.get(url).done(function(comments) {
callback(comments);
});
};
};
var CommentsViewModel = function (commentsRepository) {
var self = this;
self.CommentsRepository = commentsRepository;
self.Comments = ko.observableArray([]);
//self executing function to Get things started
self.init = (function() {
self.CommentsRepository.Get(function(comments) {
self.Comments(comments);
});
})();
};
И мы закончили!Чтобы использовать этот новый компонент, мы можем использовать RenderAction
@* inside our Layout or another View *@
<article>
<h1>@article.Name</h1>
<p>main page content here blah blah blah</p>
<p>this content is so interesting I bet people are gonna wanna comment about it</p>
</article>
@Html.RenderAction("Comments", "CommentsList", new { id = article.id })