无法从带有下拉选择更改的淘汰视图模型中筛选数据

Unable to filter data from knockout view model with drop down selection change

本文关键字:视图 淘汰 模型 数据 筛选 选择      更新时间:2023-09-26

我有一个像这样的简单控制器:

  public JsonResult GetPosts(int? id)
    {
        var varid = id;
        var ret = (from post in db.Posts.ToList()
                   orderby post.PostedDate descending
                   select new
                   { 
                       NeighbourhoodId = varid,
                       Message = post.Message,
                       PostedByName = post.ApplicationUser.UserName,
                       PostedDate = post.PostedDate.ToString(),
                       PostId = post.PostId,
                  });
        return Json(ret, JsonRequestBehavior.AllowGet);
    }

在这里,我可以得到下拉选择的值。我将它分配给一个变量variad,然后将其分配给NeighbourhoodId。

但是,当视图页面被呈现时,所有4个帖子都没有改变。但实际上,它应该只显示2个帖子。

这是我的查看页面代码:

<ul id="msgHolder" data-bind="foreach: posts">
<li class="postHolder">
<p><a data-bind="text: PostedByName"></a>: <span data-bind=" html: Message"></span></p>

以及脚本文件夹中的wallpost.js文件,所有与敲除视图模型相关的代码都在这里。它首先从数据库中正确加载所有Post,但如果我试图用下拉更改来过滤它,数据不会被过滤。

  function Post(data) {
var self = this;
data = data || {};
self.PostId = data.PostId;
self.NeighbourhoodId = data.NeighbourhoodId;
self.Message = ko.observable(data.Message || "");
self.PostedByName = data.PostedByName || "";
self.PostedDate = getTimeAgo(data.PostedDate);
self.error = ko.observable();
   function viewModel() {
    var self = this;
    self.posts = ko.observableArray();
    self.newMessage = ko.observable();
    self.error = ko.observable();
    self.loadPosts = function () {
        // to load existing posts
        $.ajax({
             url: postApiUrl,
            datatype: "json",
            contentType: "application/json",
            cache: false,
            type: 'Get'
        })
        .done(function (data) {
            var mappedPosts = $.map(data, function (item)
            { return new Post(item); });
            self.posts(mappedPosts);
        })
        .fail(function () {
            error('unable to load posts');
        });
    }
   return self;
  };
  ko.applyBindings(new viewModel());

我的下拉列表相关代码在这里:

    @Html.DropDownList("Locations", ViewBag.NeighbourhoodId as SelectList,"Select a Location")
                <script type="text/javascript">
                  $(document).ready(function () {
                  $("#Locations").change(function () {
                      var locationSelected = $("#Locations").val();
                      var url = '@Url.Action("GetPosts", "Post")';
                      $.post(url, { id: locationSelected },
                     function (data) {
                         });
                       });
                  });
                </script>

当我调试时,我在控制器中得到了正确的id值,但在过滤数据时出现了问题。淘汰赛文件需要修改吗?这里该怎么办??

与其混合jquery事件处理程序和敲除绑定,我认为最好使用敲除处理所有事件。

  1. 使用选项绑定绑定您的选择元素(下拉菜单),并在视图模型初始化时加载位置数组;将值绑定到可观察的属性,例如:"CurrentLocation"
  2. 订阅属性"CurrentLocation"的更改,例如:myViewModel.CurrentLocation.subscribe(函数(newValue){//在此处请求GetPosts})
  3. GetPosts请求的On.done()函数使用服务器接收到的项更新observableArray

希望这能有所帮助!

更新

下面是一个非常简单的例子,我改变了主意,使用"事件"绑定来处理更改事件,而不是"选项"绑定,但概念是一样的。

@Html.DropDownList("Locations", new SelectList(Model.Locations, "Id", "Name"), new { data_bind = "event: { change: reloadPosts}" })
<ul data-bind="foreach: posts">
    <li data-bind="text:CompleteText"></li>
</ul>

<script>
function Post(data) {
    var self = this;
    self.Id = ko.observable(data.Id);
    self.LocationId = ko.observable(data.LocationId);
    self.Text = ko.observable(data.Text);
    self.CompleteText = ko.computed(function () {
        return self.Id() + " " + self.Text();
    });
}
function PageViewModel() {
    var self = this;
    self.posts = ko.observableArray();
    self.reloadPosts = function () {
        $.ajax({
            type:"POST",
            url: "GetPosts",
            data: { locationId: $("#Locations").val() }
        }).done(function (data) {
            var mappedPosts = $.map(data, function (item)
            { return new Post(item); });
            self.posts(mappedPosts);
        });
    }
}
var vm = new PageViewModel();
ko.applyBindings(vm);
</script>

控制器中的GetPosts方法:

[HttpPost]
public JsonResult GetPosts(string locationId)
{
    var selectedPosts = posts.Where(x => x.LocationId == locationId);
    return Json(selectedPosts, JsonRequestBehavior.AllowGet);
}

在上面的例子中,控制器中的posts集合只是一个内存中的集合,您可能会从DB或类似的东西中读取它。

c#代码上的post类:

class Post
{
    public string Id { get; set; }
    public string LocationId { get; set; }
    public string Text { get; set; }    
}

最后使用的视图模型:

public class TestViewModel
{
    public List<Location> Locations { get; set; }
}