- New settings
REACTOR_USE_HMIN
(default:False
) if enable and django-hmin is installed components will be rendered in minified HTML to save bandwidth.
- Building system now uses poetry
- Compression of assets is with uglify-es
- When serializing
input[type=radio]
it will read the value on the input and send it - When serializing
input[type=checkbox]
it will read the value of that input and add it to the list, or returnfalse
ortrue
if it is checked
- Added a
json.Encoder
for backwards compatibility
- Fix not re-rendering and element when clicked
- :keep directive on an input will preserve the value of the input across renders
- Started using orjson for serialization of JSON
- Add better testing
- Now the JSONEncoder used can handle all the int types of numpy.
- Performance improvements in the front-end using
HTMLElement.closest
to lookup parent component and form. - Performance improvements by using
pysimdjson
. - Rename
Component.refresh
->Component._refresh
. - Rename
Component.build
->Component._build
. - Rename
Component.dispatch
->Component._dispatch
. - Rename
Component.update
->Component._update
. - Rename
Component.render
->Component._render
. - Rename
Component.render_diff
->Component._render_diff
. - Rename
Component.subscriptions
->Component._subcriptions
. - Rename
Component.refresh
->Component._refresh
. - Now in the component template you don't need to use
this
, you can access directly members of the component that are public (that do not start with "_"). Thethis
attribute will be removed in version 2.2. - As you can't us {{ this }} anymore, use {{ header }} instead.
- When
AuthComponent
orStaffComponent
detect an unauthorized user they do not send a redirect to the login URL, they just destroy themselves. - Removed :keep in favor of :override, if the user has the focus on an input reactor will not update it's value, add the directive :override replace what ever the user has there.
Compnent._get_template
loads the template from Component.template_names as it works in django generic views.Component._get_context
returns the context used to rendering the template.- Serialization of multi-select to send to the back-end.
Component.header
returns the string to put on the head of the component.
- Now a component does not serialize the all it's children state, just it's direct state to send to the server.
- You will have to rewrite your
project/asgi.py
to something simpler:
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tutorial.settings')
from reactor.asgi import get_asgi_application # noqa
application = get_asgi_application()
- The Reactor WebSocket URL changed from
/reactor
to/__reactor__
. - You need to explicitly register the reactor URL in your
project/urls.py
:
from django.contrib import admin
from django.urls import path, include
from reactor.channels import ReactorConsumer
urlpatterns = [
path('admin/', admin.site.urls),
]
websocket_urlpatterns = [
# Temporal, to keep compatibility with old client while deploying
path('reactor', ReactorConsumer),
# Final URL, remove the previous one in the next deployment and use this one instead
path('__reactor__', ReactorConsumer),
]
- Now you can place your components in a
live.py
module inside your application.
- Auto-load of the
live.py
file in all Django installed applications, aiming to discover the Reactor components. reactor.asgi.get_asgi_application
that will load the WebSocket URLs from yourproject.urls.websocket_urlpatterns
.
reactor.urls
in favor of explicitly registering the URL where the Reactor consumer us.
REACTOR_USE_HTML_DIFF
is now enabled by default.
- The settings
REACTOR_AUTO_BROADCAST
can be abool
or adict
, if it is abool
it will enable/disable completely the auto broadcast of model changes. When adict
can be like:
AUTO_BROADCAST = {
# model_a
# model_a.del
# model_a.new
'MODEL': True,
# model_a.1234
'MODEL_PK': True,
# model_b.1234.model_a_set
# model_b.1234.model_a_set.new
# model_b.1234.model_a_set.del
'RELATED': True,
# model_b.1234.model_a_set
# model_a.1234.model_b_set
'M2M': True,
}
Each key controls an specific broadcast type, if a keys is missing False
is assumed.
- Template directive
:override
is gone, use:keep
to preserve thevalue
of aninput
,select
ortextarea
HTML element from render to render.
- Method
Component.send_parent
to send an event to the parent component.
- Template filter
tojson_safe
, use piping oftojson
intosafe
instead.
- Template filter
tojson
now supports an integer argument corresponding to theindent
parameter injson.dumps
. - In the front-end there is the assumption that components IDs are unique, so this was also implemented as this in the back-end.
- If you have turbolinks you need to add
reactor.middleware.turbolinks_middleware
to yoursettings.MIDDLEWARE
, because of https://github.com/turbolinks/turbolinks#following-redirects
- Instead of writing
<div is="x-component" id="{{ this.id }}" state="{{ this.serialize|tojson }}">
, now you can do<div {{ this|safe }} >
.
- Fix missing transpilation when a DOM node was added
@reactor-added
, when an HTML element is added@reactor-updated
, when an HTML element is updated
@reactor-init
, is not triggered on any HTML element of a component when this one is initialized (appears for first time in the DOM).
- New setting
REACTOR_USE_HTML_DIFF
(default:False
), it will usedifflib
to send the HTML diff, is a line based diff not a character based one but is very fast, not likediff_match_patch
- Dependency on
diff_match_patch
had been removed, diffing was very very very slow.
- Add capability to serializer
numpy.array
andnumpy.float
as the component state.
REACTOR_INCLUDE_TURBOLINKS
is a new setting, by default toFalse
, when enabled will load Turbolinks as part of the reactor headers and the reactor redirects (Component.send_redirect
) will useTurbolinks.visit
. This also affects all the links in your application, check out the documentation of Turbolinks.
:load
directive had been removed in favor of Tubolinks.
Component.update(origin, type, **kwargs)
is called when there is an update coming frombroadcast
and it receive whatever kwargs where passed toreactor.broadcast
. You could override this method to handle the update in the way you want, the default behavior is to callComponent.refresh
.
reactor.broadcast
, now can receive parameters.