Ok, ich werde es versuchen! Dieser Code ist völlig unerprobt! Ihr Problem besteht darin, dass die Aktion nicht wissen kann, ob sie von einem Iframe aus aufgerufen wurde oder nicht, es sei denn, Sie geben ihr einen. Die Grundlage für meinen Antwortversuch ist also, dass alle URLs für Iframes einen zusätzlichen get-Parameter haben sollten. Lass uns das caller
anrufen. So sollte jeder iframe etwas aussehen
<iframe url="index.php?r=controller/action&caller=this-controller/action</iframe>
Jetzt können Sie immer die Anforderungs-URL testen, um zu sehen, ob es von einem Iframe aufgerufen wurde. Außerdem sollte für jeden Link innerhalb des Iframes dieser Parameter zu seiner URL hinzugefügt werden.
So, jetzt haben wir mindestens zwei Probleme. Erstens, wie man automatisch caller
als get
Parameter hinzufügt, ohne jede URL neu schreiben zu müssen, und zweitens, wie man die goBack()
Methode so rekonfiguriert, dass sie den Unterschied zwischen den zwei Arten der Anfrage kennt.
Das erste Problem kann relativ leicht gelöst werden, indem Sie zwischen dem Controller und der Ansicht, die Sie wollen, eine andere Ansichtsebene hinzufügen, die ich es nennen möchte iframe
. Fügen Sie das also in Ihrer Controller-Aktion hinzu;
$view = 'The name of the view you want to render';
$this->render('iframe', 'view' => $view);//Add in any other parameters you want to pass
Ihre iframe-Ansichtsdatei sollte so etwas enthalten;
<iframe src="<?php Url::to(['however you generate the url for your iframe', 'caller' => Url::to($this->context->route)]); ?>">
<?php $this->render($view); ?>//Pass additional parameters to the view if needed
</iframe>
Jetzt haben wir einen Weg, um einen controller/action
Aufruf zu testen, um zu sehen, wenn sie von am iframe angefordert werden. Der Parameter caller
ist wichtig, da er es uns ermöglicht, eine Zeichenfolge zu extrahieren, die als Wert für goBack()
und andere Methoden verwendet werden kann.
Als nächstes müssen wir UrlManager
erweitern, da alle request
, response
, Url:to()
und goBack()
Methoden und Klassen schließlich die UrlManager
verwenden, um die Verfahren zur Erzeugung von URLs zu vervollständigen.
Erstellen Sie einen neuen UrlManager. Wir werden den Großteil des Codes aus dem vorhandenen UrlManager kopieren, indem wir etwas eigene Würze hinzufügen. Ich habe meine in commands
gespeichert, aber setzen Sie Ihren Platz, wo Sie möchten, und ändern Sie den Namespace entsprechend.
<?php
namespace app\commands;
use Yii;
use yii\web\UrlManager;
class CustomUrlManager extends UrlManager {
public function createUrl($params){
$request = Yii::$app()->request;
$caller = $request->get('caller');
if ($caller && !$params['caller']){
$params['caller'] = $caller;
}
return parent::createUrl($params);
}
}
Nun erzeugt die iframe einen caller
Parameter, und jeder Link innerhalb des iframe wird auch caller
als Parameter angehängt, so lange ass Sie verwendet haben entweder Url::to()
(oder Varianten auf dieser Methode) oder Yii::$app->UrlManager
um deine Links zu generieren.
Nun müssen wir nur noch die goBack() - Methode Ihres Controllers anpassen, um alle goBack() - Anfragen an den ursprünglichen iframe zu senden.
public function goBack($defaultUrl = null)
{
$caller = Yii::$app->request->get('caller');
if ($caller){
return Yii::$app->getResponse()->redirect($caller);
}
return Yii::$app->getResponse()->redirect(Yii::$app->getUser()->getReturnUrl($defaultUrl));
}
Schließlich müssen Sie Yii konfigurieren, um Ihren neuen UrlManager in Ihrer Konfigurationsdatei zu verwenden;
'components' => [
'urlManager' => [
'class' => 'app/commands/CustomUrlManager'
]
]
Ich würde gerne wissen, ob das funktioniert, es war eine interessante Herausforderung!
Haben alle Iframes dieselbe Ansichtsseite? –
Nein, Iframes befinden sich in verschiedenen Ansichten. – Dean