JabberwockyDecompiler
JabberwockyDecompiler

Reputation: 3390

KnockoutMVC Foreach Lambda filter (or any filter)

I have been able to create a display that loops a list of pages. This will display all pages in the DB table like the following.

@using (var page = ko.Foreach(m => m.PageList))
{
    @page.Html.TextBox(p => p.PageErrorMessage)
    @page.Html.TextBox(p => p.PageSuccessMessage)
    @page.Html.TextBox(p => p.Title)
    @page.Html.TextBox(p => p.Content)
}

I am would like to be able to filter what displays by a lambda expression on the Foreach. Currently that returns the type IEnumerable, even with a ToList() at the end the following does not work.

//Note: I have tried .Where pl.Title == "string" with the same results
@using (var page = ko.Foreach(m => m.PageList.Where(pl => pl.Title.Contains("Page01")))
{
    @page.Html.TextBox(p => p.PageErrorMessage)
    @page.Html.TextBox(p => p.PageSuccessMessage)
    @page.Html.TextBox(p => p.Title)
    @page.Html.TextBox(p => p.Content)
}

I can get the results that I want, but it seems cumbersome to do this. If I add a visible check to each field with the same check I only see the fields I want.

//Note: p.Title.Contains("string") does not work for me in the Visible here
@using (var page = ko.Foreach(m => m.PageList))
{
    @page.Html.TextBox(p => p.PageErrorMessage).Visible(p => p.Title == "Page01!")
    @page.Html.TextBox(p => p.PageSuccessMessage).Visible(p => p.Title == "Page01!")
    @page.Html.TextBox(p => p.Title).Visible(p => p.Title == "Page01!")
    @page.Html.TextBox(p => p.Content).Visible(p => p.Title == "Page01!")
}

Is there a better way to work with foreach to filter down the list or is this currently designed to always return the full set?

Upvotes: 0

Views: 338

Answers (1)

Kyeotic
Kyeotic

Reputation: 19857

You cannot use C# code in razor to modify your viewmodel. To bind against something it needs a representation in the viewmodel. If you want to filter the full list, a computed property on the viewmodel should do the trick.

[Computed]
public List<Page> FilteredList
{
  get { return PageList.Where(pl => pl.Title.Contains("Page01")); }
}

Upvotes: 1

Related Questions