Re: [w3c/webcomponents] has="mixin this, mixin that" (#663)

Guys, mixing classes together (in whatever form, class factories, concatenation, etc) is adding much complexity that my idea avoids in the first place (avoiding anything to do with inheritance).

Assuming it would be named `has=""` (which I like because it is the shortest so far and the word describes which behaviors the element "has"), then in the following:

```html
<any-element has="behavior1 behavior2 behavior3" />
```

those classes are not associated by inheriatnce _at all_.

They are standalone classes, as I just described here: https://github.com/w3c/webcomponents/issues/509#issuecomment-327910080

They don't inherit from each other, there's no concatenation, prototype mangling, or any form of multiple inheritance; there's nothing about inheritance at all, to keep it simple and clean.

They are standalone behaviors, then when instantiated are given the opportunity to act on (or on behalf of) an element. They are behaviors that can run logic based on the life cycle of a given element, and they don't need to extend from each other or operate on the same `this`.

In most cases, they will probably never actually need to add or remove properties on the target element, and using their own `this` will suffice.

In less common cases, the behavior might want to expose imperative API (rather than just attribute-based API). And in such cases, [this idea](https://github.com/w3c/webcomponents/issues/662#issuecomment-327369316) (though slightly more verbose than accessing properties on an element itself) provides a way for a behavior's public API to be accessed, and encourages developers not to modify properties directly on the target element.

However, behavior authors still can modify the target element directly if they want to (just like authors of any jQuery behavior). 

In the end, this would be more similar to jQuery than multiple inheritance, in the sense that jQuery plugins can have their own `this` and APIs on that `this` can be called and properties on that `this` can be set without modifying the target element. The target element is merely a medium from which to react to, and from which behaviors can react based on the target element's (attribute) state.

F.e., in jQuery, we use behaviors like this:

```js
$(someElement).behavior('some-method', 'some-arg')
```

(This pattern is [documented here](https://learn.jquery.com/plugins/basic-plugin-creation/#minimizing-plugin-footprint))

In this jQuery example, we're passing the element to jQuery and getting back a jQuery context that lets us use a behavior associated with the element (using the aforementioned and widely-adopted pattern), and to then call a method on that behavior (not on the element directly).

In this regard, the idea in #662 is similar, in the sense that behaviors are independent of each other.

In my example where I wrote

```js
audioDiv.components['audio-player'].callWhatever()

// or

audioDiv.behaviors['audio-player'].callWhatever()
```

that is effectively similar to

```js
$(audioDiv).audioPlayer('callWhatever')
```

in jQuery, where we get a behavior associated with the target element and call a method on it.

This concept has already been proven (jQuery), just that in the current form it is _not_ declarative, only imperative.

#662 proposes something that replaces the current `is=""` attribute with something that is still declarative, more concise than jQuery's version, but also similar to jQuery's concept of standalone behaviors that are less likely to conflict than mixins of whatever form.

The idea in #662 is also better than jQuery's, because each behavior is nicely organized into a class that has its own very clear `this` context on which it can do anything it wants, and with an API like `audioDiv.behaviors['audio-player'].callWhatever()` it is possible to get the highly-individual `this` context of a behavior and call methods on it.

The pattern is simply a lot cleaner, semantic, and idiomatic than jQuery's, based on modern JS.

That said, this idea is its own, jQuery or not. The behaviors associated with an element are independent (there's no inheritance involved, and there should not be, for the sake of simplicity).

It allows any number of authors to be able to associate behaviors with any number of elements (that is similar to jQuery).

It also solves the problems with `is=""` (confusing inheritance patterns limited to only a single class (a single behavior)) and also solves the problems that `is=""` addresses (f.e. not being able to replace `<tr>` with `<custom-element>` inside a table).


-- 
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/663#issuecomment-327919677

Received on Thursday, 7 September 2017 20:33:43 UTC