web-dev-qa-db-fra.com

ReferenceError: $ n'est pas défini yii2

L'ajout d'un javascript dans ma vue se traduit par ReferenceError: $ is not defined. Je suppose que le problème est dû au fait que Yii2 injecte les derniers scripts sur ma page. Comment régler ceci?

Ou comment empêcher Yii2 de charger automatiquement les fichiers de script?

Mon avis

  <?php

   use yii\helpers\Html;
   use yii\helpers\ArrayHelper;
   use yii\helpers\UrlManager;
   use yii\widgets\ActiveForm;
   use backend\controllers\StandardController;

   use backend\models\standard;


   ?>

 <div class="domain-form">

<?php $form = ActiveForm::begin(); ?>

<?php



    <?= $form->field($model, 'clause')->textarea(['rows' => 6]) ?>

    <?= $form->field($model, 'name')->textarea(['rows' => 6]) ?>

    <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
    </div>

<?php ActiveForm::end(); ?>

   </div>

    <script type="text/javascript">
    $("document").ready( function () {
    alert("hi");
    });</script>

J'ai besoin d'obtenir ce script simple pour afficher une alerte après le chargement de la page. Je n'ai appelé aucun des fichiers de script ici depuis yii se charge automatiquement (je pense) dans la mise en page en appelant

  AppAsset::register($this);

Il en résulte des fichiers de script à enregistrer à la fin de la page, après mon script personnalisé.

Comment résoudre ça?

32
Dency G B

Yii2 injecte les scripts (jquery et similaires) en dernier sur votre page. Ceci est voulu et souhaité. Mais cela signifie que jQuery se chargera APRÈS votre script, donc lorsque votre script s'exécute, jQuery n'existe pas encore.

Le moyen le plus simple pour un test rapide est de déplacer les scripts yii (jquery et similaires) en tête de page. Modifier assets\AppAsset.php et ajoutez ceci:

public $jsOptions = array(
    'position' => \yii\web\View::POS_HEAD
);

Terminé!


Mais en production, vous voulez généralement que les scripts se chargent en dernier, et vous laissez plutôt Yii2 gérer votre javascript:

$this->registerJs(
    '$("document").ready(function(){ alert("hi"); });'
);

Maintenant Yii va gérer ce js et le placer après quelque chose d'important (comme jQuery).

Vous remarquerez cependant rapidement que les IDE sont généralement mauvais pour gérer ce type d'imbrication de langage (JavaScript dans PHP), de sorte que la mise en évidence de la syntaxe est susceptible de se casser. Une façon de le résoudre consiste à enregistrer votre script dans un fichier séparé:

$this->registerJsFile( 'myScript.js' );

Si vous voulez encore plus de contrôle sur l'ordre de chargement de vos scripts, vous pouvez ajouter des dépendances comme deuxième argument et des options supplémentaires comme troisième:

$this->registerJsFile( 
    'myScript.js', 
    ['\backend\assets\AppAsset'],  
    ['position' => '\yii\web\View::POS_END']
);

Si pour une raison quelconque vous voulez absolument que le script soit rendu en ligne, vous pouvez le faire:

$this->registerJs( $this->renderPartial('myScript.js') );

La façon recommandée d'ajouter vos scripts est d'utiliser AssetBundles . Regarder dans assets/AppAssets.php et ajoutez votre fichier js au tableau $ js.

81
ippi

Chaque fois que vous avez besoin de certains actifs pour une utilisation spécifique à la bibliothèque, enregistrez-les dans le fichier de vue comme ceci:

use yii\web\JqueryAsset;
JqueryAsset::register(this);

Sinon, si vous ajoutez yii\web\JqueryAsset à ton $depends attribut dans AppAsset, l'élément sera chargé automatiquement pour toutes vos vues, étant donné que vous l'avez enregistré dans la disposition principale (par défaut dans le passe-partout Yii2).

Je voulais utiliser la plage de dates yii2 de kartik-v dans mon projet, et j'ai fait ceci:

use kartik\daterange\DateRangePicker;
use kartik\daterange\MomentAsset;
use yii\web\JqueryAsset;

JqueryAsset::register(this);
MomentAsset::register(this);
...
echo DateRangePicker::widget([ 
    'model' => $model, 
    ...
]);

Depuis que je suis passé à twig templating, je me suis retrouvé avec le code suivant à mon avis:

{{ use('kartik/daterange/DateRangePicker') }}
{{ use('kartik/daterange/MomentAsset') }}
{{ use('yii/web/JqueryAsset') }}
{{ register_jquery_asset() }}
{{ register_moment_asset() }}
...
{{ date_range_picker_widget({ 
    'model': model, 
    ...
   }) }}
0
clapas