Angular: Introduce visibility restrictions to DI providers and directives

Created on 24 May 2017  路  9Comments  路  Source: angulardart/angular

This is a placeholder issue until I have more details to share, but tl;dr:

  • By default, nothing changes.
  • In 4.x, a visibility option will be introduced:
// On a directive/component.
@Component(
  visibility: Visibility.LOCAL,
)
class Comp {}

// On a provider.
const Provider<Foo>(visibility: Visibility.LOCAL)

Potential first enumeration of visibility (names subject to change):

enum Visibility {
  /// This provider or directive can only be injected to other directives on the same element.
  LOCAL,

  /// Default visibility: Can be injected by any directives in the entire tree.
  ALL,
}

This both helps encapsulation of public APIs, and also performance, because we generate less code when a component or provider has a more limited scope. We believe that in reality _most_ directives and components, specifically, are not injected at a later point in time. Right now we pay the cost anyway.

compiler perf 鈿ew feature

Most helpful comment

We might want to consider a NONE visibility as well.

All 9 comments

I like this idea. I think it's worth doing an experiment to see how often components expect providers to be provided by parent components.

We might want to consider a NONE visibility as well.

Especially on the provider, huge hunking +1!

A NONE visibility would be great to have.
React's components allow for similar behaviour, and it was used a lot back in the days with Apache Flex.

A visibility of NONE would enable you to write 'data' or 'service'-components like this:

<rest-service-api endpoint="http://whatever.com"></rest-service-api>

Eventually, if you would take all of this some steps further you could start doing

<my-application>
    <user-model [user]="currentUser"></user-model>
    <rest-service-api endpoint="http://whatever.com"></rest-service-api>
</my-application>

or even more importantly, you would be able to easily create components where semantics and rendering don't have to be a 1-on-1 thing:

<data-grid [data]="data">
    <column>
        <header name="Username"></header>
        <cell field="username"></cell>
    </column>
</data-grid>

Column, header and cell would be invisible components, so you could loop over them and render plain html instead:

<table>
    <tr>
        <th>Username</th>
    </tr>
    <tr>
        <td>Flappy</td>
    </tr>
</table>

For me, it's one of the missing pieces of Angular :)

should viewProviders be merged into this?

Pushed to 5x.

@dotdotcommadot I think you've misunderstood the intent of this issue. This is to add fine-grained control over where a provider is permitted to be injected, whereas you seem to be asking for creation of components without views.

@matanlurey Is this issue still relevant? Visibility control has already been added for directives. At the time I left this open because it wasn't supported for providers, but do you still see a need for that?

No, let's close this. Fixed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matanlurey picture matanlurey  路  4Comments

double11one picture double11one  路  6Comments

ranquild picture ranquild  路  6Comments

chalin picture chalin  路  3Comments

Cododoc picture Cododoc  路  6Comments