Problemas para inhabilitar la cache en AJAX

Hola, soy nueva con Yii y hasta ahora he ido adelandando bastante pero me he topado con un muro que no consigo saltar.

He creado un formulario de usuario para tratar datos de dos tablas distintas. En él tengo un select para seleccionar a una persona. Mi intención es que al canviar el selector se modifiquen los datos de los campos correpondientes a la persona. Para ello he intentado que los cambios me los haga con Ajax en una capa donde tengo todos los datos de la persona agrupados, pero mi sorpresa es que siempre me sustituye los datos por la ventana de la aplicación que tubiera en caché. Creo que he hecho todo lo que debía para solucionar el tema de la cache, poner la cache a false, incluir una variable con valores diferentes en cada intento, etc, pero no lo logro.

Este es el cógido del formulario:




  ...

<div class="row">

  <?php echo $form->labelEx($modelUser,'id_personal'); ?>

  <?php echo $form->dropDownList($modelUser,

                                 'id_personal',

                                 CHtml::listData($modelPersonal::model()->findAll(), 'id', 'nom'),

                                 array( 'empty'=>'Sense persona vinculada',

                                        'ajax' => array('type'=>'POST',

                                                        'cache'=>false,

                                                        'url'=>CController::createUrl('user/getPersonalInfo').'?s='.date('YmdHs'),

                                                        'data'=>array('id_user'=>$modelUser->id,

                                                                      'id_persona'=>'js:this.value',

                                                                      'time'=>date('YmdHs')),

                                                        'update'=>'#user-form' )); ?>

		<?php echo $form->error($modelUser,'id_personal'); ?>

	</div>




Y en el controlador:




public function accessRules()

	{

		return array(

			array(  'allow', // allow admin user to perform 'admin' and 'delete' actions

				'actions'=>array('index','view','create','update','admin','delete','GetPersonalInfo'),

				'roles'=>array('Admin'),

			),

			array('deny',  // deny all users

				'users'=>array('*'),

			),

		);

	}

...

public function actionGetPersonalInfo(){


                echo "Acción des de actionGetPersonalInfo( )";


                $id_usuari = $_POST['id_user'];

                $id_personal = $_POST['id_persona'];


                $modelUser=$this->loadModel($id_usuari); //echo $modelUser->id_personal;

                $modelPersonal = $this->loadModel_Personal($id_persona); //echo '<br>'.$modelPersonal->email;


                $modelUser->password = '';

                $modelUser->password2 = '';


                $this->renderPartial('application.views.user._form', array(

                    'modelUser'=>$modelUser,

                    'modelPersonal'=>$modelPersonal,

                ), false, true);

        }



A la acción del controlador no le hace ni caso, aunque si no encuentra la función sí que da error.

La capa la sustituye con la pàgina al completo anterior o de otro usuario, o hasta con la principal del menú. Yo entiendo que esas páginas son las que guarda en cache el navegador.

El problema no es con un navegador en concreto, me pasa con varios (FF, IE, etc.)

Muchas gracias,

Añadiendo más iformación a lo que explicava en el anterior post:

Me he dado cuenta que el problema que tengo con el Ajax es general y es debido a un comportamiento extraño con las funciones nuevas que creo en el controlador.

Por ejemplo creo una nueva función muy sencilla en el controlador, a la que llamo ‘nueva’:


public function actionNueva(){

        	echo "Función 'nueva' ejecutada";

    	}

La incluyo en las reglas de permisos:


public function accessRules()

	{

		return array(

			array(  'allow','actions'=>array('index','view','create','update','admin','delete','nueva'),'roles'=>array('Admin'),

			),

			array('deny',  // deny all users

				'users'=>array('*'),

			),

		);

	}

En principio debería de ser suficiente.

Si intento acceder a ella directamente por url me redirecciona a la pàgina principal (o función principal del controlador)

Por ejemplo estoy en : midominio/aplicacions/index.php/user

Cambio la URL para acceder a nueva: midominio/aplicacions/index.php/user/nueva

Me redirecciona a: midominio/aplicacions/index.php/user/admin

Eso mismo me pasa en la respuesta a Ajax.

Si no estubiera bien definida la función en el controlador mostraria un error 404 diciendo que no la encuentra. Pero no es así, simplemente no hace caso de la función y redirecciona hacia la página principal.

Alguien tiene alguna idea de porqué sucede esto. Seguramente me he descuidado algun detalle en el controlador pero no sé ver el qué y no logro obtener el resultado de la función.

Muchas gracias.

Al final he encontrado la solución :rolleyes:

El error era debido a un control previo de permisos que realizo a cada acción del controlador. Las nuevas acciones que creaba no superaban el control porque no le había añadido los permisos al rol correspondiente (utilizo la extensión RBAM para los permisos según Roles, tareas y operaciones).

Esta és la función del controlador que comprueba los permisos para cada acción:


protected function beforeAction($action){

        	if(Yii::app()->user->checkAccess(ucfirst($this->getId()).':'.ucfirst($this->getAction()->getId()))){

            	return true;

        	}else{

            	Yii::app()->request->redirect(Yii::app()->user->returnUrl);

        	}

  	}

Por otro lado, he corregido el problema que tenía con Ajax, que no me actualizaba correctamente la página.

Probando me di cuenta que Ajax esperaba un ‘return true’ al final de la salida de la función a la que llamaba.

El siguiente código muestra un ejemplo de aplicación AJAX para la administración de usuarios. Se crea un listado de usuarios mediante ‘CGridView’ el cual se trata como un renderizado parcial de la vista. En el pie del listado añado un botón que permite borrar todos los usuarios seleccionados a través de una función AJAX.

Espero que les pueda servir.

Listado de usuarios:




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

	'id'=>'user-grid',

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

    	'filter'=>$modelUser,

    	'columns'=>array(

            	array(

                    	'class'=>'CCheckBoxColumn',

                    	'selectableRows'=>'2', 

                    	'id'=>'chbx',

                    	'value'=>'$data->id',

		),

            	array(

                	'name'=>'id',

                	'value'=>'$data->id',

                	'htmlOptions'=>array('style'=>'text-align: left; width:5%;'),

            	),

		'username',

            	

            	array( 

                    	'name' => 'id_personal',

                    	'value' => '($data->id_personal!="")? CHtml::value(Personal::model()->find("id=".$data->id_personal),"nom",$data->id_personal):""',

            	),

            	array(

                	'name'=>'Ultim_inici_sessio',

                	'value'=>'(isset($data->Ultim_inici_sessio) && $data->Ultim_inici_sessio!="")? date("d-m-Y",strtotime($data->Ultim_inici_sessio)):""',

                	'htmlOptions'=>array('style'=>'text-align: center'),

            	),

            	array(

                	'name'=>'Habilitat',

                	'type'=>'boolean',

                	'value'=>'$data->Habilitat',

                	'htmlOptions'=>array('style'=>'text-align: center; width:5%;'),

            	),

		array(

                	'name'=>'Ldap',

                	'type'=>'boolean',

                	'value'=>'$data->Ldap',

                	'htmlOptions'=>array('style'=>'text-align: center; width:5%;'),

                	'footer' => 'Seleccionats:',

            	),

		array(

                	'class'=>'CButtonColumn',

                	'template'=>'{update}{delete}',

                	'deleteConfirmation'=>"js:'Vols borrar aquest/s usuari/s?'",

                	'footer' => '<a class="deleteall" title="Esborrar els seleccionats" href="#" onclick="borrarMultiple();"><img src="/aplicacions/assets/29f83aa7/gridview/delete.png" alt="Esborrar els seleccionats" /></a>',

		),

	),

));



Script con la función AJAX:




<script type="text/javascript">

	<!--

	$.ajaxSetup({cache: false});//Per fer que no guardi la cache


	function borrarMultiple(){

            	var usuaris = "";

            	var num = 0;

            	$("input[type=checkbox]:checked").each(function(){

                    	usuaris = usuaris +  $(this).val() +  ",";

                    	num++;

            	});

            	

            	if (usuaris.length <= 0){

                    	alert("Si us plau, selecciona els usuaris a borrar.");

                    	return false;

            	}          	

            	var aleatori = Math.random();

            	$.ajax({

               		type: "POST",

               		url: baseUrl+"/user/deleteItems",

               		data: "usuaris="+usuaris+"&a="+aleatori,

               		cache: false,

               		statusCode: { 404:function() { alert('Error 404: No se encuentra la página (archivo)'); } },

               		success: function(result){

                            	$('#user-grid').html(result); //Si la acción retorna true sustituye el listado por la salida de la función

                    	}

         		});

	}

	-->

</script>



[size=“2”]La acción para eliminar los usuarios creada en el controlador basada en la solución propuesta por [/size][size=“2”]liu1084[/size][size=“2”] en su post ‘how to delete items in GGridView(my example)’ :[/size]

:




public function actionDeleteItems(){


            	if(Yii::app()->request->isAjaxRequest) { 

                	if(isset($_POST['usuaris']) && $_POST['usuaris']!=''){


                    	$model = new User();

                    	$items = explode(',', rtrim($_POST['usuaris'], ','));

                    	$num_eliminats = 0;

                    	$num_items = 0;


                    	if(!empty($items[0])){

                        	foreach($items as $item){

                                	$sql = 'DELETE from tbl_user WHERE id = :id';

                                	$command = Yii::app()->db->createCommand($sql);

                                	$command->bindValue(':id', $item);

                                	$return = $command->execute();

                                	if ($return == 1) $num_eliminats++;

                                	$num_items++;

                        	}

                    	}

                    	$missatge = "Usuaris esborrats: ".$num_eliminats." de ".$num_items;

                	}else{

                    	$missatge = "No s'ha eliminat cap element.";

                	}


                	$modelUser = new User('search');

                	$modelUser->unsetAttributes();  // clear any default values

                	if(isset($_GET['User'])) $modelUser->attributes=$_GET['User'];

                	echo $this->renderPartial('_admin_list', array('modelUser'=>$modelUser,));

                	echo "<br><div class='missatge'>".$missatge."</div>";

                	

                	return true;

            	}else{

                	return false; //Cuando no es una acción ajax

            	}

    	}



Saludos,