0

Suppose you have a custom component container. This component will look at any html elements inside it and make desicions based on custom html attributes of those elements. For example, suppose there is a proportion attribute that could be used as follows:

<x-container>
  <div proportion="0.2">
  ...
  </div>
  <div proportion="0.5">
  ...
  </div>
  <div proportion="0.3">
  ...
  </div>
</x-container>

Forgetting dart for a second is this a reasonable thing to do with html attributes or is it an abuse? (Note: I am learning Dart and Web UI as my first attempt at web development - so this may be a bad idea).

If it is reasonable, I would like to nest containers:

<x-container>
  <x-container proportion="0.3">
  ...
  </x-container>
  <x-container proportion="0.3">
  ...
  </x-container>
  <div proportion="0.4">
  ...
  </div>
<x-container>

In general Container components themselves do not have or need proportion member variables, only their contained html elements may have proportion html attributes. But since a container can be a contained element I want it to be able to have such an html attribute. How can I set an html attribute in the instantiation of a component without it trying to call a dart method ("proportion=") on a member variable that does not and should not exist?

From the answer for How to pass a constant or literal data via an attribute while instantiating dart web component? it looks like the suggestion is attribute=value, but this attempts to set a member variable, which will not exist.

Community
  • 1
  • 1
user1338952
  • 3,233
  • 2
  • 27
  • 41
  • I'm not sure I understand, why can't you have your `x-container` with a `proportion` instance field that you use for the logic? – Kai Sellgren Jun 23 '13 at 19:28
  • I could - but seems incorrect. In this case, as writer of container, I know about _proportion_. But suppose inside of my container I am using another widget called _weather_summary_ written by some other developer with no concept of _proportion_. The same question holds. I don't know if such a use of html attributes is an abuse. If not, it seems there is no reason not to allow setting of _html attributes_ on instantiation of components. Utlimately, html attributes can be used by content provider to pass information _blindly_ to containers of components, as opposed to the component itself. – user1338952 Jun 23 '13 at 20:06
  • Now I see. Wrap `x-weather-summary` inside a `x-container`, which has the `proportion`. This is the only way I'm aware of. In WPF/XAML this kind of thing can be written like ` – Kai Sellgren Jun 23 '13 at 20:40
  • Thanks. _x-container_ code iterates over children looking for html attribute _proportion_. _x-container_ does not need _proportion_ of its own. If it has 5 children, each requesting 20% of the area via their _proportion_ html attributes then it may use *theirs* to layout. Web UI is driven by code generation. There is a set of *allowed* attributes (_name_, _extends_, _constructor_, _apply-author-styles_). Others generate call to setter on component and if it does not exist an error occurs. Why not, rather than error, if setter exists invoke it, if not set html attribute. Could be useful? – user1338952 Jun 23 '13 at 23:21

2 Answers2

1

If you are able to translate your requirements to css instead of a proportion attribute, you may be able to accomplish what you want to using an approach like the following.

In my components, I pass in a view object to the component, and the view object has style attribute, which is dynamically generated based on the values assigned to the view object;

In the partial sample below, in my component dart code I am calculating the style and class attributes using the view object that is passed at runtime.

  CardView view;
  String get cardClass => 'piece ${view.type} card classic clickable';
  Map get cardStyle => view.styles;  

And in my html code I refer to those getters as shown;

<element name="x-playing-card" constructor="PlayingCardComponent" extends="div">
  <template>
      <div class="{{cardClass}}"  on-click="select()"
        style="{{cardStyle}}">
      </div> 
  </template>
  <script type="application/dart" src="xplayingcard.dart"></script>
</element>

In a similar way, I think you can accomplish the same as the proportion attribute does, but using css.

Allan
  • 83
  • 5
  • Thanks - maybe I am not understanding. The set of html attributes of an element is effectively a dictionary. Some keys are taken (i.e. standardized: _id_, _style_, _title_, ...) others are not (_proportion_, _my_data_,...). At point of _instantiation_ client *could* stuff in that map so the *app* can see it. In this example, you are passing data _cardClass_ from code to an html attribute _class_. Useful, but different use case I think. – user1338952 Jun 26 '13 at 14:34
0

It turns out that there is a bug that prevents html attributes from being set.

Going forward:

We will be able to set html attributes without binding them when the fix is released. Additionally there will be a new requirement to specify which instantiation attributes are to be bound. Any attributes specified in html instantiation but not specified in the component element definition's attributes=... will be passed through as html attributes of the component. Additionally, in general, when passing data from html instantiation through to html attributes (by not adding them to attributes=...) it is best practice to name them data-some-unique-prefix-* and then they can be accessed via component's dataset map.

The discussion: https://groups.google.com/a/dartlang.org/forum/#!topic/web-ui/KYF6pbVk8J0

These features are actively being developed so count on changes.

user1338952
  • 3,233
  • 2
  • 27
  • 41