|
1 | 1 | --- |
2 | | -text: aasdasd |
3 | | -locked: false |
| 2 | +text: abcasdasd |
| 3 | +locked: true |
4 | 4 | --- |
5 | 5 |
|
6 | 6 | Locked: `INPUT[toggle:locked]` |
7 | 7 | ```js-engine |
8 | 8 | const mb = engine.getPlugin('obsidian-meta-bind-plugin').api; |
9 | | -
|
10 | | -const signal = mb.createSignal(undefined); |
11 | | -
|
12 | | -component.register(mb.listenToMetadata(signal, context.file.path, ['locked'])); |
13 | | -
|
| 9 | +// a component for lifecycle management of the fields created in our render function |
14 | 10 | const comp = new obsidian.Component(component); |
15 | 11 |
|
16 | | -function render() { |
| 12 | +// create a bind target to the property that we care about |
| 13 | +const bindTarget = mb.bindTargetParser.fromStringAndValidate('locked', context.file.path); |
| 14 | +
|
| 15 | +// the render function, it takes the locked value as the argument |
| 16 | +function render(value) { |
| 17 | + // first we unload the component to unload the content from the previous rerender |
17 | 18 | comp.unload(); |
| 19 | + // then we load the component again for this rerender. |
18 | 20 | comp.load(); |
| 21 | + // then we empty the element we render to to remove content created in the previous rerender |
19 | 22 | container.empty(); |
| 23 | +
|
| 24 | + // next we create the field based on the locked value |
20 | 25 | let field; |
21 | | - if (signal.get()) { |
| 26 | + if (value) { |
22 | 27 | field = mb.createInlineFieldFromString("VIEW[{text}][text]", context.file.path, undefined); |
23 | 28 | } else { |
24 | 29 | field = mb.createInlineFieldFromString("INPUT[text:text]", context.file.path, undefined); |
25 | 30 | } |
| 31 | +
|
| 32 | + // and finally we render that field |
26 | 33 | mb.wrapInMDRC(field, container, comp); |
27 | 34 | } |
28 | 35 |
|
29 | | -const reactive = engine.reactive(render); |
30 | | -signal.registerListener({ |
31 | | - callback: () => reactive.refresh(), |
32 | | -}); |
| 36 | +// we create a reactive component from the render function and the initial value will be the value of the bind target |
| 37 | +const reactive = engine.reactive(render, mb.getMetadataWithBindTarget(bindTarget)); |
| 38 | +
|
| 39 | +// then we subscribe to the metadata that the bind target points to and rerender the reactive component everythime the bind target value changes |
| 40 | +const subscription = mb.subscribeToMetadataWithBindTarget( |
| 41 | + bindTarget, |
| 42 | + (value) => reactive.refresh(value) |
| 43 | +); |
| 44 | +
|
| 45 | +// don't forget to unregister the subscription when this code block unloads |
| 46 | +component.register(() => subscription.unsubscribe()); |
33 | 47 |
|
34 | 48 | return reactive; |
35 | 49 | ``` |
36 | 50 |
|
37 | 51 | ```js-engine |
38 | 52 | const mb = engine.getPlugin('obsidian-meta-bind-plugin').api; |
39 | 53 |
|
40 | | -const signal = mb.createSignal(undefined) |
41 | | -component.register(mb.listenToMetadata(signal, context.file.path, ['text'])) |
42 | | -
|
43 | 54 | function onUpdate(value) { |
44 | | - return value.toString() |
| 55 | + return value.toString(); |
45 | 56 | } |
46 | 57 |
|
47 | | -const reactive = engine.reactive(onUpdate, signal.get()) |
48 | | -signal.registerListener({ |
49 | | - callback: (v) => reactive.refresh(v), |
50 | | -}) |
| 58 | +const reactive = engine.reactive(onUpdate, context.metadata.frontmatter.text); |
| 59 | +
|
| 60 | +const subscription = mb.subscribeToMetadata( |
| 61 | + 'frontmatter', |
| 62 | + context.file.path, |
| 63 | + ['text'], |
| 64 | + false, |
| 65 | + (value) => reactive.refresh(value) |
| 66 | +); |
| 67 | +
|
| 68 | +component.register(() => subscription.unsubscribe()); |
51 | 69 |
|
52 | 70 | return reactive; |
53 | 71 | ``` |
0 commit comments