Problemy z CGridView

Witam, zacząłem przygodę z tym frameworkiem, generalnie podoba mi się (przede wszystkim jego prędkość).

Największym problemem jest dokumentacja (baardzo uboga, kilka prostych tutoriali plus wygenerowane automatycznie API trudno nazwać dokumentacją), ale rozumiem twórców, pewnie chcą zarabiać na książkach i szkoleniach.

W każdym bądź razie utworzyłem sobie prostą aplikację, z pomocą utworzonej wcześniej bazy danych oraz narzędzia yiic utworzyłem modele oraz wygenerowałem odpowiednie kontrolery i widoki (CRUD).

I teraz mam taki problem: są dwie tabele: Text (z kolumnami id, typeId, name) oraz Type (z kolumnami id , description).

Kolumna typeId tabeli Text jest kluczem obcym do Type(id).

Chciałbym zmodyfikować utworzony automatycznie widok tabeli Text tak, by pokazywał nie samą wartość typeId lecz wartość pola description odpowiedniego rekordu tabeli Type.

Mam teraz coś takiego




$this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'text-grid',

	'dataProvider'=>$model->search(),



Z tego co zrozumiałem muszę skonstruować i przekazać obiekt dataProvider (ale jaki - CActiveDataProvider czy CDataProvider ?)

Czy dobrze myślę? Jak taki obiekt utworzyć ??

Kod, który podałeś wywołuje metodę search() modelu danych. Jeśli zajrzysz do rekordu aktywnego (modelu) dla tabeli text to w metodzie search() na samym końcu powinieneś znaleźć coś takiego:




return new CActiveDataProvider(get_class($this), array(

  'criteria'=>$criteria,

));



Zatem zwracany jest obiekt typu CActiveDataProvider (CDataProvider jest klasą abstrakcyjną).

Widżet


CGridView

wyświetla domyślnie wszystkie wartości "tak jak leci". Jeśli chcesz to zmienić, to musisz zdefiniować jego właściwość


$columns

. W twoim przypadku powinieneś zmodyfikować kolumnę


$typeId

mniej więcej tak:




$this->widget('zii.widgets.grid.CGridView', array(

        'id'=>'text-grid',

        'dataProvider'=>$model->search(),

        'columns'=>array(

          'id', 

          //tutaj zaczyna się modyfikacja

          array(

            'name'=>'typeId',

            'value'=>'$data->types->description',

          ),

          //a tu się kończy <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/smile.gif' class='bbc_emoticon' alt=':)' />

          'name'

        )

);



Uwaga:


$data->types

odnosi się do zdefiniowanej relacji w modelu w metodzie


public function relations()

super, działa, dzięki za (jakież to teraz oczywiste ;) ) tą linijkę:


'value'=>'$data->types->description',

… oraz za szybką odpowiedź.

i jeszcze korzystając z tej dobrej passy zapytam : czy jest możliwość również filtrowania po tej nazwie (description), gdy podam dodatkowo dla CGridView:


	'filter'=>$model, 

???

pozdrawiam :)

Jeśli mówisz o filtrze w nagłówku, to wystarczy, że dodasz parametr filter




array(

  'name'=>'typeId',  

  'value'=>'$data->types->description',

  'filter'=>Type::model()->findAll()

),



Jeśli nie zadziała, to możesz rezultat


Type::model()->findAll()

potraktować


CHtml::listData()

i wyglądałoby to mniej więcej tak:




  array(

    'name'=>'typeId',  

  'value'=>'$data->types->description',

  'filter'=>CHtml::listData(Type::model()->findAll(),'id','description')

),



Wielkie dzięki, poniższa linijka


CHtml::listData(Type::model()->findAll(),'id','description')

działa super :)

pozdrawiam!

Czy do tego typu operacji konieczne są zdefiniowane klucze obce w bazie?

z tego co pamiętam to nie (ale ręki bym sobie nie dał obciąć) :D.

Z pewnością jednak, jeśli masz zdefiniowane klucz obce to rozszerzenie powłoki: yiic shell tool czy też przeglądarkowe Gii wygenerują Ci relacje, które pomogą w odczytywaniu powiązanych rekordów.

Proponuję zatem krótki test:

  • stwórz dwie tabelki, np. parent_table z polami id, title oraz child_table z polami id, parentid, title i zdefiniuj klucze obce. Potem pododawaj parę wierszy. Następnie wygeneruj sobie klasy AR dla tych tabel a następnie usuń w bazię relacje pomiędzy polem parentid a id tabeli parent_table. Następnie stwórz sobie instancję AR dla child_table i zassaj odpowiednie dane rodzica. Powinno zadziałać na mój gust.

P.S. Zaproponowałem, aby na początku stworzyć jednak te relacje, aby było łatwiej wygenerować klasy AR :) Oczywiście nie jest to warunek konieczny :)

Mam dwie tabele:

  1. Z listą domen - porobione linki w widoku CGridView

  2. Z większą liczbą kolumn (również listą domen) - widok CGridView

Chcę zrobić tak aby kliekając na domenę z listy w jednym widoku wyświetlało mi tylko wiersze odnośnie tej domeny z drugiego widoku i dnia wczorajszego (jedna z tabel posiada datę)

Dodatkowo chciałbym wykorzystać dodanego search() w 1.1.1 w taki sposób aby po kliknięciu na utworzony link w widoku CGridView wyszukiwało wiersze tylko tego elementu na który kliknąłem (tutaj bez żadnych rejacji, jedna tabela).

Co do kluczy obcych to właśnie nie chce by było tak, że są zależności podczas usuwania rekordów, tylko odczytywania :)

Jeżeli mógłbym prosić o naprowadzenie jak bym to mógł zrealizować to byłbym bardzo wdzięczny :)

ja mam jeszcze jedno (właściwie trzy) pytania do CGridView:

  1. Już fajnie wyświetlają mi się nazwy z powiązanych kolumn , ale sortowanie (gdy kliknę na nagłówek) nadal jest po id a nie po wyświetlanym opisie. Da się to zmienić ?

  2. Czy można mieć wpływ na wyświetlane kontrolki w każdym wierszu (pokaż/popraw/usuń) ? Powiedzmy chcę tylko mieć dwie pierwsze ?

  3. Czy można zmienić napisy "Displaying 1-10 of 10 result(s)." i potwierdzenie przed usunięciem rekordu ?

Z góry dziękuję za wszelkie podpowiedzi :)

[update]

Punkt 2 już wiem :) Trzeba przedefiniować CButtonColumn, reszta pytań bez zmian.

Ad 2. Trzeba zmienić właściwość template klasy CButtonColumn

Ad 3. Tutaj musisz zmienić właściwość summaryText aby zmienić podsumowanie. Natomiast zmiana komunikatu to nadpisanie deleteConfirmation

Na koniec zostawiłem najtrudniejsze (podam tylko wędkę - rybę będziesz musiał złowić sam :))

Zatem Ad 1. Sortowanie w CGridView, jak odsyła dokumentacja, wykorzystuje dataProvidera, w Twoim przypadku zapewne CActiveDataProvider. Tam zaś zobaczysz, że właściwość sort to tak naprawdę implementacja klasy CSort. Więc musisz pokombinować z właściwościami tej klasy. Ew możesz sprawdzać w akcji czy $dataProivder->sort->orderBy zawiera nazwę kolumny id, jeśli tak, to wtedy sortujesz którąś z funkcji sortowania tablic dane z dataprovidera (ale to niekoniecznie musi działać, to jedynie idea).

Powodzenia

dzięki, punkty 2 i 3 faktycznie proste, z 1 będę kombinował, dzięki na razie za pomoc :)

Że tak pozwolę sobie odgrzać starego kotleta, z maja dokładnie, i napisać trochę off-topic, ale mi się lekko flaki przewróciły…

Eee, Misiu! :) Nie pomyliły Ci się frameworki? Baaardzo uboga dokumentacja?

A:

[list=1]

[*]The Definitive Guide

[*]Building Blog with Yii Example

[*]Cookbook

[*]Yii Playground

[/list]

to niby co?

W ogóle znalazłeś / widziałeś / czytałeś te dokumenty? Bo trzeba być bardzo odważnym, żeby dokumentację w ilości około 300 stron A4 (nie licząc wspomnianej Class Reverence, która ma ponad 1000 stron) napisaną naprawdę przystępnym językiem i do tego przetłumaczoną na język polski nazwać… bardzo ubogą!

Jakby Ci było mało to jest jeszcze Larry Ulman’s Introduction to the Yii Framework i kilkadziesiąt kolejnych stron poświęconych programowaniu z Yii.

P.S.: Z tego, co się orientuję, to autor jedynej jak dotąd książki o Yii (wydanej notabene w sierpniu 2010 r., więc nie mogłeś mieć o niej bladego pojęcia pisząc te słowa w maju) nie ma nic wspólnego z zespołem deweloperów Yii i oni na pewno nie zarabiają na fakcie jej istnienia. A o szkoleniach (tym bardziej płatnych) z Yii też jakoś nie słyszałem.

Więcej respektu na przyszłość polecam! :)

Człowieku odgrzałeś kotleta z maja 2008 roku. Wtedy prawdopodobnie nie było dużo materiałów o yii w języku polskim.

Eee…

Posted 05 May 2010 - 10:02 PM

Ja bym raczej powiedział, że z maja 2010, czyli jakieś nieco ponad pół roku temu!

A materiałów o Yii w języku polskim to nadal jest bardzo mało. Ale kto bierze się za programowanie w jakimkolwiek języku nie znając angielskiego na poziomie umożliwiającym czytanie dokumentacji z jako takim zrozumieniem?