eigener For-ViewHelper ohne each-Array [Gelöst]

  • harald1972 harald197...
    Sternenflotten-Admiral
    0 x
    198 Beiträge
    13 Hilfreiche Beiträge
    14. 04. 2013, 11:43

    Hallo Leute,

    bei den ganzen Fluid-ViewHelpern vermisse ich einen FOR-ViewHelper.
    Es gibt zwar einen, der so heißt, aber eigentlich ist das ja ein FOREACH-ViewHelper.
    Die Parameter $each und $as sind zwingend vorgesehen.

    Ich möchte aber gern einen ViewHelper, der in etwas so aufgerufen werden soll:

    1. <my:customFor init="1" max="10" step="1" as="x" >
    2. do_something_with{x}
    3. </my:customFor>

    Dabei soll x nur integer-Werte von (in diesem Beispiel) 1 bis 10 annehmen.
    Ich möchte also nicht über ein Array iterieren. Weil ich aber zwingend eins haben soll, erzeuge ich eben ein Array = {1,2,3,4,...}
    Ich denke, sowas könnte nützlich sein, und ich wundere mich echt, daß es sowas noch nicht gibt. 8-)
    Ich hab dazu den Tx_Fluid_ViewHelpers_ForViewHelper genommen und davon folgendes abgeleitet:

    1. class Tx_Myextension_ViewHelpers_CustomForViewHelper extends Tx_Fluid_ViewHelpers_ForViewHelper {
    2.  
    3. public function initializeArguments() {
    4. parent::initializeArguments();
    5. $this->registerArgument('init', 'integer', 0, FALSE, 0);
    6. $this->registerArgument('max', 'integer', 0, FALSE, 0);
    7. $this->registerArgument('step', 'integer', 0, FALSE, 1);
    8. }
    9.  
    10. /**
    11.   * the render method
    12.   *
    13.   * @param string $as
    14.   * @param string $key
    15.   * @param boolean $reverse
    16.   * @param string $iteration
    17.   * @return string
    18.   */
    19. public function render($as, $key='', $reverse=FALSE, $iteration=NULL) {
    20. $each = array();
    21. for($i= intval($this->arguments['init']); $i<=intval($this->arguments['max']); $i+=intval($this->arguments['step'])){
    22. $each[$i]=$i;
    23. }
    24. parent::render($each, $as, $key, $reverse, $iteration);
    25. }
    26. }

    Soviel zu meinem Ansatz.
    Nur funktioniert das so nicht.
    Vielleicht sieht ja jemand, wo hier mein Denkfehler ist.
    Ich hab schon einiges ausprobiert, komm aber nicht auf die Lösung. :'(


  • 1
  • kainobi kainobi
    Jedi-Ritter
    0 x
    141 Beiträge
    0 Hilfreiche Beiträge
    15. 04. 2013, 07:54

    Ich glaube Du musst

    1. return parent::render($each, $as, $key, $reverse, $iteration);

    schreiben.

  • harald1972 harald197...
    Sternenflotten-Admiral
    0 x
    198 Beiträge
    13 Hilfreiche Beiträge
    15. 04. 2013, 09:32

    Klingt so trivial wie logisch...

    [quote="kainobi"]
    Ich glaube Du musst

    1. return parent::render($each, $as, $key, $reverse, $iteration);

    schreiben.
    [/quote]

    hilft mir aber nicht :(
    Ich bekomm nichts gerendert.

    Ich hab jetzt testweise mal einen alert in die render-Methode gesetzt, um mir mein $each ausgeben zu lassen.
    Das Array sieht eigentlich ganz genau so aus, wie es sein soll (zumindest denk ich, daß es so sein soll), also {1=>1, 2=>2,...}

    Dabei taucht aber noch ein Punkt auf, den ich nicht verstehe:
    Der alert wird nur ausgelöst, wenn ich den cache geleert habe. Ohne den cache zu leeren, wird beim Neuladen der ViewHelper nicht angestossen - wenigstens wird kein alert ausgelöst.

  • kainobi kainobi
    Jedi-Ritter
    0 x
    141 Beiträge
    0 Hilfreiche Beiträge
    15. 04. 2013, 10:59

    Meiner Meinung nach ist das mit dem Alert normal, wenn es eine cacheable controller action ist.

  • harald1972 harald197...
    Sternenflotten-Admiral
    0 x
    198 Beiträge
    13 Hilfreiche Beiträge
    15. 04. 2013, 18:52

    Das mit der cacheable action hab ich mir auch schon mal gedacht.
    Ich hab meinen Test (mit dem alert) gleich in die list-action von meiner Aggregatwurzel.
    Und die hab ich bei den non-cacheable actions drin... extra deswegen.
    Trotzdem wird der alert nur ausgelöst, nachdem ich den cache geleert habe.

    Aber das ist ja eigentlich gar nicht mein Problem - ich denke auch nicht, daß es damit zu tun hat.
    #paralyzed# ...naja, wer weiß... #evil#

  • harald1972 harald197...
    Sternenflotten-Admiral
    0 x
    198 Beiträge
    13 Hilfreiche Beiträge
    15. 04. 2013, 20:37

    Da bin ich wieder, zwar nicht sonderlich schlauer oder irgendwie weiter, aber ich hab nochmal was festgestellt.

    Ich hab spaßeshalber mal folgendes ausprobiert:
    Die render-Methode um $each erweitert, also die selben Params wie parent-Klasse

    1. public function render($each, $as, $key='', $reverse=FALSE, $iteration=NULL) {
    2. for($i= intval($this->arguments['init']); $i<=intval($this->arguments['max']); $i+=intval($this->arguments['step'])){
    3. $each[$i] = $i;
    4. }
    5.  
    6. foreach($each as $key => $val){
    7. $this->alert($key.'=>'.$val); }
    8.  
    9. return parent::render($each, $as, $key, $reverse, $iteration);
    10. }

    ($this-alert() sorgt für javascript-alert)
    und dieses fluid/html-code
    1. <my:customFor each="{0:0}" init="1" max="5" step="1" as="y" key="x">
    2. <p> {x}: {y} </p>
    3. </my:customFor>

    Ich gebe also ein 0-Element im each-array mit (wodurch bestenfalls 1 Element zuviel erzeugt wird).
    Ich bekomme (korrekt) den alert von 0 bis 5.
    Gerendert wird aber nur

    0: 0

    #evil#

  • harald1972 harald197...
    Sternenflotten-Admiral
    0 x
    198 Beiträge
    13 Hilfreiche Beiträge
    15. 04. 2013, 21:25

    So! :):):)

    Jetzt hab ich's !

    Wer also gern einen For-ViewHelper ohne zwingendes each-Array haben will, kanns gern verwenden.

    1. /**
    2.   * the render method
    3.   *
    4.   * @param string $as The name of the iteration variable
    5.   * @param string $key The name of the variable to store the current array key
    6.   * @param boolean $reverse If enabled, the iterator will start with the last element and proceed reversely
    7.   * @param string $iteration The name of the variable to store iteration information (index, cycle, isFirst, isLast, isEven, isOdd)
    8.   * @return string Rendered string
    9.   */
    10. public function render( $as, $key='', $reverse=FALSE, $iteration=NULL) {
    11. for($i= intval($this->arguments['init']); $i<=intval($this->arguments['max']); $i+=intval($this->arguments['step'])){
    12. $this->arguments['each'][$i] = $i;
    13. }
    14. return parent::render($this->arguments['each'], $as, $key, $reverse, $iteration);
    15. }

    Anstatt $each als Parameter zu übergeben, verwende ich $this->arguments['each']
    Obwohl ich es nicht in der Argumentliste hab, hab ich es vom parent geerbt und beschreibe dieses Array einfach, wie es mir passt :p

    Nachtrag: da war ein Tippfehler. Da stand...

    1. return parent::render($this->arguments['$each'], $as, $key, $reverse, $iteration);

    ... seltsamerweise hat es trotzdem funktioniert :o

  • 0 x
    17 Beiträge
    0 Hilfreiche Beiträge
    21. 06. 2013, 22:10

    Hier wäre auch was fertiges gewesen:
    [url=]http://www.auxnet.de/blog/blog-post/2012/02/16/typo3-schleifen-viewhelper-fuer-fluid.html[/url]

    Und hier noch weiteres:
    [url=]http://www.auxnet.de/blog.html[/url]

    Gruß
    Ara

  • harald1972 harald197...
    Sternenflotten-Admiral
    0 x
    198 Beiträge
    13 Hilfreiche Beiträge
    27. 06. 2013, 09:30

    Okay,

    1. Glaub mir: ich hab wie besessen gesucht und nichts gefunden.

    2. Die Links tun bei mir nicht (es fehlt der Doppelpunkt hinter http, wenn ich draufklick)

    3. Ich habs mir trotzdem angeschaut. ;) folgende Unterschiede hab ich festgestellt:
    Max Kalus geht den Weg über templateVariableContainer add und remove.
    Imho geschieht das aber in der parent::render.
    Deswegen ist parent::render, die einzige Methode, die ich aufrufen muss.
    Die Variable "variable" oder "variableName" ist auch redundant, weil "as" schon definiert ist.
    Ich verwende $this->arguments[...], Max Kalus nicht.
    Den Unterschied im letzten Punkt hab ich selbst nicht genau verstanden.

    Harald

  • 1