dotvvm icon indicating copy to clipboard operation
dotvvm copied to clipboard

Disable content in DotvvmMarkupControl

Open exyi opened this issue 2 years ago • 2 comments

By default, DotvvmMarkupControl allows children. The children are appended into the markup control, after the control's content. This is counterintuitive and will not work if used from another markup control ($control will resolve to something else than expected).

We should put [ControlMarkupOptions(AllowContent = false)] on it.

exyi avatar Dec 29 '22 16:12 exyi

What about that we allow content in markup controls? What if you want to handle the content yourself and append it manually?

Mylan719 avatar Jan 09 '23 20:01 Mylan719

It's problematic.

First, you can always add a default content property or override this setting with [ControlMarkupOptions(AllowContent = true)] if you know what you are doing. If you want to place the content into a correct placeholder, using a property is more ergonomic anyway (of type DotvvmControl or ITemplate).

However, I don't think that adding a first class support for templates in markup controls is possible. Main problem is that we change the data context in the MarkupControl, but any control or template from outside will expect the unchanged context. In basic cases, it tends to work, if you would want to place the template into a changed data context, it would most likely resolve the data context incorrectly (especially in combination with _parent references). The template would have to know in which data context will it appear, and we could even resolve this automatically, but then you run into other problems.

@viewModel object

<div>
   <dot:TemplateHost Template={resource: Template} />
</div>

The data context in this case is System.Object, so any property you attempt to use in a binding will not exist.

<dot:Repeater DataSource={value: X}>
   <dot:Repeater DataSource={value: Y}>
      <dot:TemplateHost Template={resource: Template} />
   </dot:Repeater
</dot:Repeater>

When you ask for _this in the template, you'd probably expect to get the element of list Y. But when you ask for _parent would expect it to be element of X, not the data context where the markup control is placed? _parent2 does not even exist inside the markup control, but there could be an exception for that...

When you use a code-only control, there are no data context type changes, so none of these problems exist. We could add another kind of markup controls which don't change the data context either, and call them inline markup controls. I just don't think that is worth it for an unusual use case with a reasonable workaround (composite control)

exyi avatar Jan 10 '23 19:01 exyi