Re: [w3c/webcomponents] Repurposing the is="" attribute to allow multiple behaviors to be attached to a given element (#662)

As @jimmont suggested, maybe `has=""` is the best name as it doesn't conflict with existing `is=""` that people may currently expect, however limited and confusing the feature is.

Here's an example based on what I like best so far from the three discussions (#509, #662, #663):

```js
class Foo {
  connectedCallback(el) {
    // do something with el
  }
}


class Bar {
  attributeChangedCallback(el, attr, oldValue, newValue) {
    // do something with el's changed attribute
  }
}
```

```js
behaviors.define('foo', Foo)
behaviors.define('bar', Bar)
```
```html
<!-- it "has" these behaviors -->
<any-element has="foo bar" />
```

But the defining part could also be

```js
components.define('foo', Foo)
components.define('bar', Bar)
```
```html
<!-- it "has" these *components* -->
<any-element has="foo bar" />
```

---

If `components` or `behaviors` are properties on the global, maybe it would be better to name them more specifically:

```js
elementBehaviors.define('foo', Foo)
elementBehaviors.define('bar', Bar)
```

or

```js
elementComponents.define('foo', Foo)
elementComponents.define('bar', Bar)
```

---

Going with "behaviors", here's what it looks like on a shadow root:

```js
root.elementBehaviors.define('foo', Foo)
root.elementBehaviors.define('bar', Bar)
```

---

And here's what getting those components from an element and calling a method looks like:

```js
anyElement.behaviors.foo.someMethod()
```

---

Here's an entity-component example. Imagine some game made with Custom Elements (rendering to WebGL for the sake of awesome):

```html
<ender-man has="player-aware holds-block" holds="dirt" position="30 30 30">
</ender-man>
<play-er position="40 40 30">
</play-er>
```

then later the player gets away and the ender man behaves differently:

```html
<ender-man has="holds-block" holds="sand" position="30 30 30">
</ender-man>
<play-er has="diamond-armor horse-inventory" position="100 150 40">
</play-er>
```

---

One might think, why not just use attributes, like the following?

```html
<ender-man player-aware="true" holds="dirt" position="30 30 30">
</ender-man>
```

Well, then this means that there can only be _one_ class associated with the `ender-man` element, and this is just a Custom Element.

The downside of this is to handle multiple piece of logic, they need to be encapsulated in a single class (f.e. `EnderMan`). If those multiple behaviors are to be re-usable independently of other behaviors, then they would have to somehow be mixed into the single class, and now we're introducing more complexity and more likelihood for conflicts.

So the approach where behaviors can be entirely separate classes (but with Custom Element callbacks) is a win because they can all be decoupled from each other more-so than mixing stuff into a single class.

---

Behaviors can be added and removed. In the above example, when we removed the `player-aware` behavior (which made the Ender Man try to attack the player), you can imagine that just like Custom Elements, perhaps the `detachedCallback` was called.

Or, maybe for behaviors, there could be something else like a `removedCallback` which is similar to `detachedCallback` except that it represents when the behavior is removed from the element, not when the element is removed from DOM.

It would be possible, for example, to have logic specifically for when the behavior is removed, and logic for specifically when the element is detached (but the element still have the behavior).

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/662#issuecomment-327945806

Received on Thursday, 7 September 2017 22:39:14 UTC