Zugriff auf $model in der Sidebar

Hallo zusammen,

ich habe offensichtlich ein Verständnisproblem mit den Instanzen von Klassen und der Gültigkeit dieser Instanzen innerhalb des Frameworks.

Folgendes Problem:

Ich verwende /layouts/column2 und möchte in der Sidebar ein Suchformular einbauen, mit welchem man in den Datensätzen suchen kann und das Ergebnis dann in der "Haupt"-View ausgegeben wird.

Diese Suche habe ich schon in einer View erfolgreich verwendet, und diese View wird auch brav gerendert (also das Suchformular mit renderPartial und das Ergebnis mit render()), aber nur innerhalb der "Haupt"-View, all dem, was in column2 mit echo $content ausgegeben wird.

Die Frage ist nun: Wie kann ich ausserhalb von $content auf mein $model zugreifen?

Beim render() oder $renderPartial() muss ich ja $dataProvider und/oder $model mitgeben, aber dieses "Mitgeben" scheint nur innerhalb der Klasse zu funktionieren, deren Ergebnis irgendwann in $content landet.

Und nun weiss ich nicht, wie ich da eine Querverbindung zu einem Widget/Portlet herstelle, welches ich in die Sidebar packe.

Vielleicht kann mir jemand ein bis anderthalb Augen öffnen.

Vielen Dank und viele Grüße

Ralf

Hallo Ralf und willkommen im Forum,

solche Probleme tauchen immer wieder mal auf. Jeder Request muss ja prinzipiell erst mal von einer Action bedient werden. Nach dem was du schreibst, hast du ja schon eine Action für die Suche. Was spricht dagegen, das Suchformular in der Sidebar einfach auch auf diese Action verweisen zu lassen? Falls das ein Weg ist, könntest Du die Action im Widget konfigurierbar machen und so die Wiederverwendbarkeit erhöhen.

Hallo Mike,

vielen Dank für deine Antwort.

Ich habe das Problem eben gelöst, und zwar ziemlich trivial:

Es wurde in meinem Suchformular in der Sidebar ja immer bemängelt, dass ich etwas auf ein Objekt anwenden will, welches nicht da ist, nämlich $model, welches ich in dem Objekt des Widgets CAktiveForm verwende.

In einfach:

Folgendes funktionierte nicht. Dabei muss man wissen, dass das in einer _testview.php steht, die in /layouts/column2.php mit renderPartial(’_testview’) gerendert wird:




<?php 

	$form=$this->beginWidget('CActiveForm', array(

	'action'=>Yii::app()->createUrl('tickermeldung/index'),

	'method'=>'get',

)); ?>


<?php echo $form->textField($model,'TEXT'); ?>

<?php echo CHtml::submitButton('Suchen'); ?>


<?php $this->endWidget(); ?>



Hier wurde immer gemosert, dass $model nicht da ist, bzw. überhaupt ein Objekt fehlt.

Ich kam lange Zeit nicht auf die einfachste Lösung:

Nämlich $model noch einmal zu instanziieren:




<?php 


	$model=new TickerMeldung('searchitem');

	$form=$this->beginWidget('CActiveForm', array(

	'action'=>Yii::app()->createUrl('tickermeldung/index'),

	'method'=>'get',

)); ?>


<?php echo $form->textField($model,'TEXT'); ?>

<?php echo CHtml::submitButton('Suchen'); ?>


<?php $this->endWidget(); ?>



Jetzt funktioniert es wie gewollt. Ich hoffe nur, es ist auch sauber :slight_smile:

Viele Grüße

Ralf

Würd sagen, nicht 100% sauber, da im View eigentlich keine Models mehr instanziiert werden sollten. Aber wenns läuft, isses andererseits erst mal o.k. Überarbeiten kann man den Code später immer noch, wenn man merkt, dass es von der Trennung her (MVC) mehr Probleme macht.

Okay, ich würde es gerne sauber machen. Die Frage ist nur, wie?

Die Sidebar scheint losgelöst von allem, was in $content wohnt, zu existieren.

Ich hatte folgendes in der column2.php versucht:




<?php $this->renderPartial('_testview',array(

	'model'=>$model,

)); ?>



Aber dabei hat die Zuweisung von $model nicht geklappt. Diese kam scheinbar nicht in ‘_testview’ an.

Siehe Fehlermeldung:




Fatal error: Call to a member function getValidators() on a non-object in



Die Frage, die ich mir nicht beantworten konnte, ist also, wie ich ‘model’ in column2 befüllen kann, dass ‘_testview’ richtig gerendert wird.

Eine Möglichkeit wäre z.B. sowas in der Art in deinen Basiskontroller (components/Controller.php) einzubauen:




private $_searchModel;


public function getSearchModel()

{

    if ($this->_searchModel===null)

        $this->_searchModel=new TickerMeldung('searchitem');

   return $this->_searchModel;

}

Jetzt kannst du überall (also in Controller und View) einfach mit $this->searchModel das Model beziehen. Singleton schon eingebaut.

Hallo Mike,

ich glaube, ich verstehe so langsam…

Wäre es aber nicht so, dass ich den "_" mit angeben muss, also: $this->_searchModel wenn ich auf das Model referenzieren will?

Oder fällt der Underscore ausserhalb der Methode dann unter den Tisch?

Viele Grüße

Ralf

PS: Ich würde es auch ausprobieren. aber das ganze Geraffel liegt im Büro :slight_smile:

Eben gerade nicht, weil CController auch eine Komponente ist. Was das bringt, findest du hier:

http://www.yiiframework.com/doc/guide/1.1/de/basics.component

Es hat etwas gedauert… :slight_smile:

Aber ich glaube, jetzt habe ich das Prinzip der Getter und Setter halbwegs verstanden.

Ich habe das vorher nicht mit meinem ursprünglichen Problem in Verbindung gebracht.

Jetzt habe ich das Ganze hier mal nachgebaut mit der Beispielanwendung… und siehe da, das Rendern klappt problemlos über den Weg, den du oben beschrieben hast :slight_smile:

Es ist also so, dass die Controller-Klasse der Ort ist, wo ich Eigenschaften definiere, die ich übergreifend benötige, um sie dann einfach später zu referenzieren.

Tja, vielen Dank! :slight_smile:

Ralf

Ich würde "wo ich Eigenschaften definieren kann" sagen, muss nicht für alles der beste Ort sein. Aber ja, für diesen Fall würd ich sagen passt. Brauchst du eine Eigenschaft z.B. nur über mehrere Actions, aber immer nur im selben Controller, machst du die Getter-Methode natürlich in diesen speziellen Controller statt in den Basiscontroller. Sonst wird letzterer mit der Zeit überladen.