A template set can now obtain a template by calling the function
getTemplate (if any) received in the initial config.
The returned value can be an Element instance, a template string, a
function (i.e. a compiled template), or null. In the last case, owl will
look into the template set rawTemplates object.
A few corrections to make the example more realistic:
- The component has no `error` property, so the writer probably meant `state.error`.
- The "content" slot is not being set, and "default" does the job in this case.
- The closing tag was missing in the `ErrorBoundary`'s template.
Before this commit, most of the time, components are destroyed when the
virtual dom is patched and a component node is removed. However, since
Owl is asynchronous and a component may take some time to get ready
(with onWillStart), it can happen that a component is created, then
before it is ready, it is recreated. In that case, the initial instance
has to be destroyed.
Before this commit, the destroy operation was done immediately, when we
cancel the current fibers. However, this means that we cannot have a
guarantee between micro task ticks that a component has not been
destroyed in the meantime.
For example, in Odoo, it is common to use the rpc service, which will
throw an error if called by a destroyed component. But because of the
possible destruction of a component at any time, the following code is
unsafe:
async loadSomeData() {
// guaranteed to be called when component is alive
await Promise.resolve();
// however here, component may have been destroyed
this.rpc(...)
}
So, to prevent this issue, we can slightly delay the destroy operation.
It is not entirely trivial, since we need to find a way to neutralize
the component in the meantime. But it seems like performing all that
kind of operation at the "commit" phase (so, the request animation frame
callback) makes sense to me.
So, this commit modifies the code to add a new component status
(cancelled) and use it to cancel components that are waiting to be
destroyed. These components will then be destroyed as soon as the
requestanimation frame starts, before all other dom operations.
Going from owl 1.0 to 2.0, we removed the possibility of having a
reference to a component. However, the documentation was not properly
updated to reflect that.
In JS, objects are often used as a mapping that gives fast lookup on the
keys, in those cases, the keys themselves are not known in advance, but
the values may have a shape that they're expected to follow. This commit
adds support for a `values` key in schema for objects, which will be
checked against all values in the object during validation.
This commit adds the devtools as a zip file containing both chrome
and firefox versions of the extension in the release and also updates
the doc to install it easily.
This commit adds the code of the owl devtools extension.
This extension can be added on chrome or on firefox for
developpers to be able to inspect the contents of all owl
applications that are present on any web page, see all the
components, interract with them and their content to some
extend and perform a bit of profiling with their renders.
It is common in Owl components to have anonymous function as props.
However, since each rendering create a different (but equivalent)
closure, Owl will consider the props different, so will update the child
component, but this is (often) not necessary.
This commit will help reduce the problem by introducing a new `.alike`
prop suffix, that will let Owl know that each version of that specific
prop should be considered the same, so, will be ignored by the props
comparison code.
closes#1360
t-call-context is a feature that's supposed to mask the rendering
context completely, but currently the component remains available
through `this`.
This commit stops treating `this` as a reserved word, so that it's
compiled to a lookup in the rendering context, and adds `this` to the
rendering context when binding the component's rendering function. With
these changes, `this` behaves the same as before when outside a
t-call-context, but when the rendering context is overriden, the
template can no longer access `this`. `this` still represents the
instance of the component inside of the rendering function since it's
needed by owl internally.
A side-effect of this change is that now the rendering context is no
longer the instance of the component by default, but is always an object
with the component in its prototype chain. This was already the case
before in some contexts (eg inside t-foreach, or inside components with
a t-set/t-call anywhere in its template). This can cause issues in rare
cases when a component method was called directly on the rendering
context, as before this change, the method's bound this would be the
component instance (except in a t-foreach, component with a
t-set/t-call, etc), while after this change it is now never the
component instance. When the method only reads on `this` there is no
issue as all the components properties are available on the rendering
contexts, but setting a value on `this` will write on the rendering
context and not the component which is likely a mistake.
While this is a breaking change, simply adding a t-set/t-call to any
template would break components that would be broken by this change,
with this in mind we decided to make this change anyway so that
developers get the error as early as possible in the development cycle
rather than having a seemingly inocuous change break code under them.
The `useEffect` has two parameters:
* The `effect` function
* The `computeDependencies` function
The `effect` function always take as parameters the result
of the `computeDependencies` function.
Expliciting this allows to better understand the `useEffect`
behaviour and the following example in the doc:
```
useEffect(
(el) => el && el.focus(),
() => [ref.el]
);
```
In app.js, `mount(Root, document.body, { dev: true, env });` crash because `body` is not available yet.
Therefore, moving the script into the body fix the issue.
This commit add supports for value types in prop validation. To describe
a value V type, one has to simply write {value: V}.
Note that this commit also improves the validation typing.
closes#1198closes#910
The props validation code is actually quite difficult to get right.
Also, it is sometimes useful to be able to validate an object against a
specified schema. Therefore, this commit exports the standalone validate
function as an utility function.
Previously, components would automatically call useState on their props,
so that changes deeply within props would automatically cause the
component to be rendered. This can be useful when passing a piece of
state to children or descendants.
One problem with this is that all props implicitly become reactive, even
if the object that was passed as a props was not. The problem with that
being that since the original object is not reactive, any change made by
the parent will not go through the reactivity system and the children
won't be notified of the change, in essence, this reactive object is
essentially useless, while having a real cost: traversing reactive
objects creates more reactive objects, and those objects are all
proxies. This is expensive for basically no benefit, while also making
it more difficult to debug code that involves those objects.
This commit fixes that by only calling useState on objects that are
already reactive, allowing the usecase described in the first paragraph
without the drawbacks described in the second.
The Context api was retired in owl 2.0, but a documentation file was
kept alive. This commit removes it, to prevent confusion in the future.
Thanks zerone40 for the issue
closes#1180
With this commit, we make sure that the `render` method was explicitely
called with the deep === true argument, instead of assuming that it is a
boolean. This prevents errors when some unrelated value is given to the
render method. This could happen in some cases, such as
useBus(someBus, 'someevent', this.render)
In that case, the `useBus` code would simply call the this.render with a
customevent, which would be considered truthy before, and not anymore
This commit adds a warning when an async hook
(onWillUpdateProps/onWillStart) takes longer than 3 seconds, as these
hooks block the rendering and patching of the application, it is rarely
desirable and often a sign of a deadlock. This warning will contain the
stack trace of the call to the hook to help in debugging.