Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the differences between using <compose view-model="./my-element"> and <my-element>? What are some scenarios where one is more suitable?

A teammate and I have been building an application in Aurelia for the last four months, and he and I have been creating and using components in these two different ways. I want to have some consistency and change everything over to one of the two styles, but I don't know which one is preferred or more suitable for our needs.

I chose to use <compose> because to me it feels cleaner and suits every need I have encountered, but if using the custom element is objectively better I want to switch to that.

For example:

(his-way view-model:)

import { bindable, bindingMode } from 'aurelia-framework';

export class HisWay {
  @bindable({ defaultBindingMode: bindingMode.twoWay }) data;
}

(his-way view:)

<require from="./his-way"></require>
<his-way data.two-way="myModel" containerless></project-name>

(my-way view-model:)

export class MyWay {
  activate(model) {
    this.model = model;
  }
}

(my-way view:)

<compose view-model="./my-way" model.bind="myModel" containerless></compose>

Do I need to change over, and if not, what are some reasons I can use to persuade him to using the same style that I have been using?

like image 516
Anj Avatar asked Aug 11 '16 01:08

Anj


3 Answers

Use the custom element approach when possible.

Compose targets dynamic scenarios. If your <compose> element's view and view-model attribute values are static (not data-bound) you probably should have used a custom element for the reasons described below.

Portablity: Custom elements are more portable because they have a higher degree of encapsulation. A custom element's template cannot access the outer scope, all data must be passed in via @bindable properties. This contrasts with <compose>, which allows accessing the outer scope, making it very easy to get sloppy and make assumptions about the environment in which a composed view will be used.

Features: Custom elements have more features than the <compose> element. Template parts/slots (transclusion), bindable properties, ability to "globalize" via globalResources and more.

Reuse: It's much easier for a team to reuse a widget when it's encapsulated in a custom element and globalized via globalResources. The team can simply write <mega-widget ...></mega-widget> as opposed to having to remember the relative path to mega-widget.html and mega-widget.js and write a valid <compose view="..." view-model="..."></compose> expression.

Better fit: Any use-case where you are creating a data-entry widget really deserves a custom element. It's far easier to use a currency custom element- eg: <currency value.bind="unitCost"></currency> than it would be to try and achieve similar results with <compose>. Not sure how you would accomplish it really.

CSS: it's easier to target a custom element with css selectors than a specific compose element instance. mega-element { display: block; ... }

https://www.danyow.net/aurelia-custom-element-vs-compose/

like image 97
Jeremy Danyow Avatar answered Nov 15 '22 00:11

Jeremy Danyow


The answer is no. You don't need to switch over for situations like the example provided. The Compose element (i.e. Components) and Custom Elements solve different problems. The former allows you to compose a view or view and viewmodel pair into another view. The default behavior matches up views and viewmodels based on name but I understand you could actually bind a different viewmodel each time (which might give some interesting uses in say, a for loop.) I use Components when I want to break a larger view down into more manageable chunks. I will also use them where I want code reuse, but I am not looking to customize it too much from one use to another e.g. footer, navigation.

Custom Elements I understand are basically WebComponents, an evolving web standard that takes advantage of the Shadow DOM. (You can read more about that at links below.) While similar, they have a lot more power than a simple Component and IMO a greater ability for reuse. Unlike a Component, a Custom Element can have a range of bound attributes and therefore give you more control over it as you use it in a view. The example of your teammate's doesn't really do them justice. One could argue that a Component would be a better choice in that situation.

  • Aurelia Hub - Custom Components
  • Aurelia Hub - Templating: Custom Elements Basics
  • Aurelia Custom Elements & Content Selectors - April 2015
like image 27
Robb Vandaveer Avatar answered Nov 14 '22 22:11

Robb Vandaveer


I personally wouldn't force yourself into only using a certain approach. Most frameworks suffer from the fact that they try to convince you that there is only one winning paradigm. But thats not true since each project, and even inside the project each requirement can be completely different.

So when looking at whether to render components using the custom element name vs compose, first ask yourself what is the design goal you want to achieve. Unification in my opinion is not enough.

Going only with the custom-element approach is great because its easy to read and easy to get going for a kinda static page structure. On the other hand if your page requires a lot of dynamic composition, the composed approach as the name suggests is the way to go.

So I'd tend to agree that compose is better or lets say more flexible, but at the same time also kinda verbose.

One argument against compose can be the use of custom attributes. E.g. if you use aurelia-i18n and would like to use the attribute-translation approach, you'd be better off using the custom-element syntax. So as you see its really all about the use-case.

EDIT:

If we really want to go down to the nitty gritty, the best argument for the custom element approach is that compose itself is actually nothing more than a custom element.

like image 1
zewa666 Avatar answered Nov 15 '22 00:11

zewa666