[ android~paranoid @ 26.09.2010. 20:06 ] @
Ako u modelu imam kolekciju (spisak nekih podataka iz baze) kako da prikažem te rezultate po stranicama u View?
[ mmix @ 27.09.2010. 10:03 ] @
po "skolski" u skladu sa filozofijom napravis novu rutu

/[controller]/[action]/[id]/[page]



npr

/Products/View/2/4

ili alternativni route bez id-a

/Products/List/4

gde je 4 cetvrta strana



Druga opcija ti je Ajax.
[ android~paranoid @ 27.09.2010. 23:21 ] @
Ok, smislio sam, napravio sam još jednu ( pored ListaPrva() ) metodu za klik na stranice.

public ActionResult ListaStranica(int page, Collection<Product> Lista)

Pitanje je kako da prosledim ovoj metodi Listu iz View-a? To bi bila cela lista koja se dobija upitom ka bazi ( iz ListaPrva() ) pa bih izdvojio deo koji mi treba za stranicu i prikazao.
[ mmix @ 28.09.2010. 07:38 ] @
JA nisam siguran da je to moguce, mislim da precenjujes sposobnosti MVCa :) Osim ako nesto kriticno nisam propustio parametri Action metode stizu direktno iz routinga a URL encoding kompleksnih tipova mi deluje, hmm, zeznuto. AKo neko zna bolje nek kaze.
[ android~paranoid @ 28.09.2010. 08:54 ] @
:) . Ipak je ono što mi je bilo potrebno Session da sačuvam tu listu, a ne da je prosleđujem svaki put. Hvala.
[ mmix @ 28.09.2010. 09:43 ] @
Jeres pravi MVC programeri ne koriste session state Ako kontroler kesira podatke u session state-u onda vise ne postoji separacija od http contexta (bye, bye testing)

Sad realno, imaj samo u vidu da je tvoj paging view sada zavistan od kreiranja session kesa, nemoj podrazumevati da ce ga neko kreirati za tebe jer view moze da se pozove direktno kroz URL.
[ Toxter @ 28.09.2010. 10:08 ] @
Da li ti samo zelis da ucitas sledeci Page ili postback-ujes trenutni page nazad ?
[ mmix @ 28.09.2010. 10:17 ] @
Nema postback-a u MVCu. Nemas kontrolu nad klasom iz View-a (niti je postojanje klase obavezno, to je samo za WebForms renderer) samim tim nemas gde ni da hvatas postback.
[ Toxter @ 28.09.2010. 10:23 ] @
Lapsus, mislio sam da li zeli da POST-uje formu nazad ili treba da radi paging prikaz neke kolekcije.
Ako je ovo drugo onda je to prilicno jednostavno pa mogu da ponudim resenje.
[ mizob @ 28.09.2010. 10:25 ] @
Zar ne moze da posalje id objekta ajaxom, i da onda uzme kolekciju koja mu je potrebna ili u modelu da ima metodu koja ce da mu vrati kolekciju?

Ako sam dobro razumeo sta android~paranoid zeli. Postoji opcija i da ja nisam dobro razumeo :)
[ Toxter @ 28.09.2010. 10:38 ] @
Citat:
Milos Zobenica: Zar ne moze da posalje id objekta ajaxom, i da onda uzme kolekciju koja mu je potrebna ili u modelu da ima metodu koja ce da mu vrati kolekciju?

Ako sam dobro razumeo sta android~paranoid zeli. Postoji opcija i da ja nisam dobro razumeo :)


Pa upravo to. Posalje id, pageNumber i pomocu Ajaxa povuce samo tu kolekciju.
U akciji kontrolera iscupa potrebne elemente kolekcije i vrati PartialView. A na kraju taj partial view samo umetne u odredjeni <div> koji je placeholder za listu.

Jednostavno.
[ mmix @ 28.09.2010. 10:45 ] @
da, to je ajax pristup, za koji ti opet treba routa kroz koju ces serveru da posaljes id i page number, jedina razlika je sto koristis partial view umesto punog. Problem ovde je sto je on hteo da utera collection u get action metod.
[ mizob @ 28.09.2010. 10:57 ] @
Evo jedan primer...

Model:
Code:

public string MojaKolekcija
{
    get
    {
        return (ovde vratis tu kolekciju npr u html-u u view-u, tipa imas private metodu koja ce vratiti podatke i napraviti html koji ti je potreban);
    }
    private set
    {
        ;
    }
}



View:
Code:

 <div>
              <%= Model.MojaKolekcija %> 
 </div>




Znam da ne bi trebao da tamo pisem html, ali mislim da mu je ovako najlakse za pocetak
[ mmix @ 28.09.2010. 11:07 ] @
lol

kad si vec tu sto onda i cuvas podtke u bazi, cuvaj XHTML pa ga seci kroz parametrizovan XSLT za razne stranice
[ mizob @ 28.09.2010. 11:16 ] @
Citat:
mmix: lol

kad si vec tu sto onda i cuvas podtke u bazi, cuvaj XHTML pa ga seci kroz parametrizovan XSLT za razne stranice ;)



Rekoh iznad da ne treba i da mislim mu je za pocetak najlakse ovako.

:-)

Da obrisemo onda prethodni post ? ;-)
[ mmix @ 28.09.2010. 11:22 ] @
Ma nema potrebe, znamo da je zezanje. Nego ima tu i malo zastrasujuceg faktora, ko zna sta se sve moze naci u "divljini" danas na novopecenim mvc projektima. Ako oni svi imaju cistu MVC/MVVM separaciju onda sam ja cica stanko hajduk. Al vzano da je hip i moderno
[ mizob @ 28.09.2010. 11:29 ] @
:-)
[ android~paranoid @ 28.09.2010. 11:40 ] @
Nisam radio sa AJAX-om, ali probaću i tako.
Uglavnom, rešio sam problem, imam pored Modela klasu View Model kojoj prosleđujem delove Liste tj. stranice koje treba da prikažem, kao i broj stranica.

View
Code:

        <% for (int i = 1; i < Model.brojStranica + 1; i++ )
           { %>
              
           <%: Html.ActionLink(i.ToString(), "ListaStranica", new { page = i })%>

        <% } %>


Napraviću još proveru da li session objekat postoji u slučaju za koji je rekao mmix.
[ mizob @ 28.09.2010. 11:51 ] @
Mislio sam u prethodnom postu i ovaj primer da napisem, ali tad bi me tek MMIX napao :-D
[ mmix @ 28.09.2010. 12:09 ] @
Sto? Koliko sam ga ja razumeo ima poseban ViewModel koji vraca samo podset podataka iz modela i njih renderuje kroz view, spearacija nije narusena (ako zanemarimo prckanje po session state-u u modelu ). A primer koji je ostavio je koncept generisanja page link liste. Nemam nikakav los komentar na to.

Pun MVC pristup bi bio imati viewmodel koji bi ucitao samo zahtevan podatke (koristeci Skip i Take LINQ ekstenzije) bez kesiranja.

Ili moze i sa kesiranjem ali samo kroz domain-level kesiranje. Npr vidi ovde: http://stevescodingblog.co.uk/net4-caching-with-mvc/ sa tim da naravno kes sluzi svima pa ovaj primer moras da prosiris sa thread sinhronizacijom. Samo session kesiranje je veoma pipavo sa MVCom jer bi isti trebao da je potpuno stateless (osim mozda u viewu).
[ android~paranoid @ 02.10.2010. 19:29 ] @
Citat:
Toxter: Pa upravo to. Posalje id, pageNumber i pomocu Ajaxa povuce samo tu kolekciju.
U akciji kontrolera iscupa potrebne elemente kolekcije i vrati PartialView. A na kraju taj partial view samo umetne u odredjeni <div> koji je placeholder za listu.

Jednostavno.


Tako nešto sam i uradio, sa tim da koristim isti kod za formiranje tih delova kolekcije kao i bez AJAX-a.

Code:

    <% using (Ajax.BeginForm("ListaAjax", new { page = 1 },
    new AjaxOptions { UpdateTargetId = "results" }))
    { %>
    <%=Html.TextBox("query",null, new {size=40}) %>
    
    <input type="submit" />

    <div id="results">
       <% Html.RenderPartial("ListaSearchResults", ViewData.Model);%>
    </div>

    <% for (int i = 1; i < Model.brojStranica + 1; i++ )
    { %>
              
      <%: Ajax.ActionLink(i.ToString(), "ListaAjax", new { page = i }, new AjaxOptions { UpdateTargetId = "results" })%>

    <% } %>

    <%} %>


Kako mogu da napravim da kad se klikne na broj stranice ne pomeri cela stranica?
[ Toxter @ 02.10.2010. 19:58 ] @
Tako sto ce ti linkovi koji su u stvari page number biti nesto slicno ovome:
Code:
<a href="#" onclick="goToPage(1)">1</a>


ovo gotopage(1) (broj unutar predstavlja u stvari stranicu) generises na tvom View-u (ili direktno koristeci for petlju, ili sto je cistije pomocu html helpera, koristeci TagBuilder).

Zatim definises javascript funkciju:
Code:
function goToPage(pageNum){
//ovde najbolje pomocu jQuery-ja pozovi preko Ajax-a akciju tvog kontolera koja ti vraca PartialView (tj. samo kolekciju koja se menja a ne citav Model)
}


Pozdrav
[ branimir.ts @ 03.10.2010. 12:53 ] @
@android~paranoid
Citat:
public ActionResult ListaStranica(int page, Collection<Product> Lista)
Pitanje je kako da prosledim ovoj metodi Listu iz View-a?


@mmix
Citat:
JA nisam siguran da je to moguce, mislim da precenjujes sposobnosti MVCa :)

Ti si bas hejter sto se tice Ms tehnologija, pa ih mozda zato i potcenjujes - cekaj, nemoj unapred :)

Evo (samo jednog od nacina) kako moze da se dobije tipizirana lista u metodi kontrolera slanjem parametara iz view-a:

Jedna stavka koja je cesto overlooked u asp net mvc je ModelBinder - mehanizam koji omogucava mapiranje
raw http requesta u parametre action metoda controllera. Svaki put kada do kontrolera stigne http request u key/value formi, poziva se
DefaultModelBinder koji omogucava da se raw http request pretvori u nesto "opipljivije", typed net objekat recimo (sto ce u nasem slucaju biti lista) objekata).
E ako zelimo da customizujemo nacin na koji ce se http request mapirati u parametre metoda, potrebno je, koliko znam da se uradi sledece:

Primer modela:
Code:

public class NewsPaper
{
      public string Make { get; set; }
       public int Id { get; set; }
 
       public static List<NewsPaper> GetNewsPapers()
       {
            return new List<NewsPaper>
                           {
                               new NewsPaper { Id = 1, Make = "Blic"},
                               new NewsPaper { Id = 2, Make = "Novosti"},
                               new NewsPaper { Id = 3, Make = "Politika"}
                           };
       }
}

Zatim metod kontrolera:
Code:

[HttpPost]
public ActionResult PostNewsPapers(List<NewsPaper> newspapers)
{
      return .....
}


E sada ako imas multi select html kontrolu post na ovu metodu ne bi radio (naravno).
Zato pravimo klasu koja ce implementirati IModelBinder interface
Code:

public class SelectListModelBinder : IModelBinder
{
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var incomingData = bindingContext.ValueProvider.GetValue("newspapers").AttemptedValue;
            return incomingData.Split(new char[1] { ',' }).Select
                    (data => NewsPaper.GetNewsPapers().
                            FirstOrDefault(o => o.Id == int.Parse(data))).ToList();
        }
}

Imamo referencu bindingContext i u njoj Request.Form vrednosti multiple select liste. Odatle vracamo NewsPaper objekat popunjen poslatim vrednostima.

U Application_Start() registrujemo:
Code:
ModelBinders.Binders.Add(typeof (List<NewsPaper>), new SelectListModelBinder());


Da bi smo koristili custom model binder potrebno je postaviti prefix u metodu kotrolera, ispred tipizirane liste
Code:

public ActionResult PostNewsPapers([ModelBinder(typeof(SelectListModelBinder))] List<NewsPaper> newspapers)
{
      .....
}


Ovo je proof of concept za neke use casove, prilicno interesantno i ne bas jako tesko :)

Postoje i drugi nacini da se ovo uradi, ali drugi put :)

[Ovu poruku je menjao branimir.ts dana 03.10.2010. u 14:09 GMT+1]
[ mmix @ 03.10.2010. 13:32 ] @
Kako njemu to pomaze sa ovim problemom?

Kako izgleda ti njemu predlazes da celu listu (svih stranica) prosledi HTML stranici, da je onda postuje nazad serveru da bi isti kroz modelbinder napravio parametar za action metod? I to je jednostavnije i bolje od ponovnog ucitavanja sa SQLa ili cak server side kesiranja?

I nisam hejter MS tehnologija vec hejter fanbojizma bilo koje vrste, ukljucujuci i MSa.
[ branimir.ts @ 03.10.2010. 14:04 ] @
Citat:
Kako njemu to pomaze sa ovim problemom?


Nadam se da shvatas da ovo nema primenu kod pagiranja - samo mala demonstracija (jednog) extensibility pointa kod MVC frameworka.
Covek je lepo pitao da li je moguce da se uradi ovako nesto :)

A kako bih ja izveo ovo pagiranje, reci cu ti odmah - ne bih se petljao na ovakav nacin kao sto toxter i on rade, vec bih:
U modelu definisao
Code:

public interface IPageableInfo
    {
        int PageCount { get; set; }
        int PageIndex { get; set; }
    }

    public interface IPageable<T> : IPageableInfo
    {
        IEnumerable<T> Page { get; set; }
    }

2. U controlleru
Code:

public ActionResult Index(int? page)
        {
            return View(service.GetPageable(page ?? 1, 10));//vraca strongly typed IPageable<T>
        }

3. U view-u custom extenzija
Code:
        
  <%=Html.Pagination() %>
 


[ android~paranoid @ 03.10.2010. 20:46 ] @
Citat:
Toxter
ovo gotopage(1) (broj unutar predstavlja u stvari stranicu) generises na tvom View-u (ili direktno koristeci for petlju, ili sto je cistije pomocu html helpera, koristeci TagBuilder).


Ok, ovo sam uradio baš preko helpera i dobio.

Citat:
[url=/p2707650]
Zatim definises javascript funkciju:
Code:
function goToPage(pageNum){
//ovde najbolje pomocu jQuery-ja pozovi preko Ajax-a akciju tvog kontolera koja ti vraca PartialView (tj. samo kolekciju koja se menja a ne citav Model)
}

Pozdrav


Nešto sam pokušavao ali ne ide mi baš:

Code:

       function goToPage(pageNum) {
           $('#results').load("ListaAjax", pageNum);
       }


Ovo je kod na Master page, uljučio sam i MicrosoftAjax.js .

Ako može pomoć.
[ Toxter @ 03.10.2010. 21:35 ] @
Nesto ovako (pisem iz glave pa mozda ima nekih sintaksnih gresaka):
Code:


function goToPage(pageNum) {
$.ajax({
    url: pagingControllerActionUrl,   //ovo je lokacija tvoje akcije kontrolera, npr http://localhost/App1/People/GetList
    data: "id=" + pageNum,
    success: function(result) {
      $('#listDiv').html(result.toString());  //ovo smesta partial view u tvoj listDiv (koji je samo placeholder)
    }
  });
}     


I onda moras imati akciju GetList u kontrolleru PeopleController:
Code:

public ActionResult GetList(int id)
{
  List<People> list = ... //iscupas kolekciju za pageNum == id
  return PartialView("MyListPartialView", list);
}


P.S. za sada koristi ovaj pristup sa id kao parametrom akcije. Ako si malo iskusniji, znaces kako da definises rutu pa ovaj default id mozes promeniti.

Pozdrav


Edit: Naravno, moras imati partial view MyListPArtialView.ascx koji zna da renderuje kolekciju List<People> (ili vec koja ti je kolekcija).
[ android~paranoid @ 04.10.2010. 08:08 ] @
Citat:
Toxter: Nesto ovako (pisem iz glave pa mozda ima nekih sintaksnih gresaka):
[code]



Šljaka i to brže nego kad nije preko AJAX-a, ali ne radi ono što sam ja mislio, opet mi pomeri stranu, tj. klizač na gore kad odaberem stranu.
[ Toxter @ 04.10.2010. 08:31 ] @
Koji "klizac" ?

Ako mislis na scroll bar, to ti je je najverovatnije css-ovski scroll jer imas negde overflow:auto.
Ali, ovako definitivno bi trebalo da ti ucita sledecu stranu, tako da scroll bar i treba da pocinje sa vrha.

Ili ja ne shvatam sta pokusavas da postignes?

Pozdrav,
[ android~paranoid @ 05.10.2010. 07:38 ] @
Citat:
Toxter: Koji "klizac" ?

Ako mislis na scroll bar, to ti je je najverovatnije css-ovski scroll jer imas negde overflow:auto.
Ali, ovako definitivno bi trebalo da ti ucita sledecu stranu, tako da scroll bar i treba da pocinje sa vrha.

Ili ja ne shvatam sta pokusavas da postignes?

Pozdrav,


U ASP.NET je:

Page.MaintainScrollPositionOnPostBack = true;
[ android~paranoid @ 10.10.2010. 19:18 ] @
Citat:
Toxter: Tako sto ce ti linkovi koji su u stvari page number biti nesto slicno ovome:
Code:
<a href="#" onclick="goToPage(1)">1</a>


ovo gotopage(1) (broj unutar predstavlja u stvari stranicu) generises na tvom View-u (ili direktno koristeci for petlju, ili sto je cistije pomocu html helpera, koristeci TagBuilder).



Ovo je ok, link mi je http://localhost/Controller/Action# , ali kad odem sa recimo druge stranice (iz broja stranica) na neku treću (recimo link iz jednog reda zapisa) i vratim se sa back (browsera) on ne ostane na toj drugoj strani, već bude na prvoj. Gde da tražim rešenje problema?