turbine
turbine copied to clipboard
Manipulating DOM imperatively
How do you attach jquery or imperative widgets?
I'm asking for onrendered hook.
There is no official api for this yet, but it can be done by declaring a component using a class
extending Component.
You can use imperative code in the run
method, which is given a very limited api for the parent and a destroyed
future meant for cleaning up.
A small example of this is the TextComponent
class TextComponent extends Component<{}, {}> {
constructor(private t: Showable) {
super();
}
run(parent: DomApi, destroyed: Future<boolean>): Out<{}, {}> {
const node = document.createTextNode(this.t.toString());
parent.appendChild(node);
destroyed.subscribe((toplevel) => {
if (toplevel) {
parent.removeChild(node);
}
});
return { available: {}, output: {} };
}
}
export function text(showable: Showable): Component<{}, {}> {
return new TextComponent(showable);
}
Judging by the domapi interface there's no way of passing info up to the parent, like inserted widgets interface?
I'm not entirely sure what you want to archive, but the api is for manipulations. One way to pass information to a parent is as output, but that might not be what you want. Another approach is to make a parent, which supplies it children with something else than the DOMapi, which is bit more work.
Could you be a bit more specific of what you would like to do?
Use this widget https://webtorrent.io/docs
It creates a client that Id like to use.
I'm assuming you also want to use file.appendTo(elm)
,
The quick solution is to wrap the client code inside run
.
Here is an example using one of the examples from WebTorrent:
class WebTorrent extends Component<{}, {}> {
constructor() {
super();
}
run(parent: DomApi, destroyed: Future<boolean>): Out<{}, {}> {
// Container element for files
const elm = document.createElement("div");
parent.appendChild(elm);
var client = new WebTorrent()
// torrentId could be given as argument
client.add(torrentId, function (torrent) {
var file = torrent.files.find(function (file) {
return file.name.endsWith('.mp4')
})
// Use the container element for the files
file.appendTo(elm)
})
destroyed.subscribe((toplevel) => {
if (toplevel) {
parent.removeChild(elm);
}
// removes the client when the component is remove
client.destroy()
});
return { available: {}, output: {} };
}
}
I forgot to mention that I want to change the file being used in the element after intialization too.
On Thu, Jun 18, 2020, 2:33 AM Emil Gjørup [email protected] wrote:
I'm assuming you also want to use file.appendTo(elm), The quick solution is to wrap the client code inside run. Here is an example using one of the example from WebTorrent:
class WebTorrent extends Component<{}, {}> { constructor() { super(); } run(parent: DomApi, destroyed: Future
): Out<{}, {}> { // Container element for files const elm = document.createElement("div"); parent.appendChild(elm); var client = new WebTorrent() // torrentId could be given as argument client.add(torrentId, function (torrent) { var file = torrent.files.find(function (file) { return file.name.endsWith('.mp4') }) // Use the container element for the files file.appendTo(elm) }) destroyed.subscribe((toplevel) => { if (toplevel) { parent.removeChild(elm); } // removes the client when the component is remove client.destroy() }); return { available: {}, output: {} }; }} — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/funkia/turbine/issues/120#issuecomment-645578456, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACWP5AMXNZR73M67SNJ3TE3RXEK7JANCNFSM4N6MPBEA .
If it is changed based on some logic outside the component then you can provide the information to the constructor, otherwise you can just do the change inside run
by manipulating elm
Do you mean passing down a stream as a prop? How does that look like, I'm not familiar with using classes.
We hope to have a cleaner api for wrapping imperative code in the future without using classes, but until then:
class FileContainer extends Component<{}, {}> {
constructor(private stream: Stream<File>) {
super();
}
run(parent: DomApi, destroyed: Future<boolean>): Out<{}, {}> {
...
// access the stream through `this`
this.stream.subscribe((file)=> ...)
...
}
}
function fileContainer(files: Stream<File>) {
return new FileContainer(files);
}