Esta es la tercera entrada en la documentación de una aplicación web que recibe actualizaciones en tiempo real, utilizando crossbar,python y ahora un poco de vues. El objetivo de hoy es tener una chat muy muy básico con lo mínimo necesario que puedes encontrar en la documentación vuejs
El plan sería algo como :
- crear una ruta que reciba un post en klein
- hay que aprender a servir archivos estáticos en klein
- en el index.html hay que agregar el js de vuejs
- hay que aprender a enviar peticiones post desde vuejs
Pues comencemos con lo que hay que hacer en klein. buscando en su documentación justo tiene el ejemplo que sería el siguiente
https://klein.readthedocs.io/en/latest/examples/handlingpost.html
Agregamos esto a nuestro app.py
webapp.msgs = []; # esto va arriba
@webapp.route('/msg', methods=['POST'])
def do_post(request):
content = json.loads(request.content.read())
webapp.msgs.append( dict( text=content["msg"] ) )
wampapp.session.publish('com.example.msg', webapp.msgs )
response = json.dumps(dict(the_data=content), indent=4)
return response
El siguiente paso es servir los archivos estáticos los JS, css etc nuevamente en la documentación ya tienen un ejemplo.
https://klein.readthedocs.io/en/latest/examples/staticfiles.html
Volvemos a editar el app.y
import json
from twisted.web.static import File
@webapp.route('/static/', branch=True)
def static(request):
return File("./static")
Creamos un nuevo directorio con el nombre static y en este creamos un app.js que es donde colocaremos nuestra lógica de vuejs más adelante
Ahora editamos el index.html, aquí cambia un poco , pues vamos a mover todo lo que es js a un archivo y solo vamos a dejar el html
Una cosa con la que me tope, fue que tanto jinja con vuejs utilizan {{}} para imprimir o desplegar las variables pero colocando {% raw %} {% endraw %} se soluciona.
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="http://localhost:8080/js/autobahn.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
{% raw %}
<fieldset id="app" >
<legend>{{title}}</legend>
<div id="container">
<ul>
<li>Listado</li>
<li v-for="msg in msgs">
{{ msg.text }}
</li>
</ul>
<div id="input">
<textarea v-model="newMsgText" ></textarea><button v-on:click="send" >Enviar</button>
</div>
Status: {{status}}
</div>
</fieldset>
{% endraw %}
</body>
<script type="text/javascript" src="/static/app.js"></script>
</html>
y por último nuestro app.js
var data = {
title : "Chat",
status :'En Espera',
newMsgText: 'Escribe tu mensaje',
msgs:[]
}
var vm = new Vue({
el: '#app',
data: data,
methods: {
send: function(event){
var self = this;
fetch('/msg', {
method: 'POST',
body: JSON.stringify({ msg:self.newMsgText})
}).then(function(response) {
self.newMsgText = "";
});
}
}
})
var connection = new autobahn.Connection({url: 'ws://localhost:8080/ws', realm: 'realm1'});
connection.onopen = function (session) {
console.log(data);
data.status = 'conectado';
function onevent(args) {
data.msgs = args[0]
}
session.subscribe('com.example.msg', onevent);
};
connection.open();
Puedes utilizar la capacidad reactiva de VueJs al asignar otro valor a los data, que recibe como paramatros, en el ejemplo serian la linea data.status o data.msgs, tiene que ser uan asignacioón con "=" si quieres actualizar un elemento del array no se puede, tienes que sobrescribir el array completo con la modificación
y vovlemos a ejecutar
docker-compose up -d crossbar
docker-compose up -d web
Añadir nuevo comentario