-
Notifications
You must be signed in to change notification settings - Fork 232
Expose "@visibleForTemplate" (for 2.1.0 SDK) #930
Comments
Where would this annotation live so it could be useful as a lint?
|
I'd like it as part of |
Could we do anything here in the angular compiler, or would this just apply the the analysis plugin? |
How would this interact with unit tests? Would you still be allowed to access these members directly or would you have to query the DOM? |
Ideally both. My idea: Stage 1
Stage 2
Stage 3
We can probably stop here; internally we won't allow opt-outs after a point. ... having this as part of the analyzer proper will be easier than putting it directly in the compiler (and we could never block you using it dynamically, i.e.
Very good question. No idea, it would be reasonable to say its also visible to your own |
I'll phrase my question a little differently: How could we implement this in the compiler? I personally think this is a great addition to the analysis plugin, but not sure it will actually be feasible in the compiler. |
No idea, but unless we make the plugin fail builds I'm not sure how to enforce it. |
I generally think that annotations that are related to the Dart language in general belong in |
One disadvantage is we don't have a great way to re-use code you already have for the other meta annotations in our own tools. |
Couldn't this also be accomplished with more finely-grained visibility restrictions (besides public/package private). For example, some concept of friend libraries or similar to only expose the getter to the generated template.dart.file |
Yes, but I don't control that :) |
Of course! But if @visbleForTemplate is not feasible for Angular to implement, then it seems like a good feature request to have more visibility options. Then @visibleForTemplate would only have to slightly alter code generation. |
Yeah, ideally we'd have a more general:
... or similar 😄 (friends, etc). But might take much longer. /cc @lrhn @leafpetersen for FYI. |
The code to check for invalid use of an annotation tends to be different for each annotation and fairly small, so we don't have a lot of sharing internally for this either. The quick fixes are a little more involved, but we've tried to make it very easy for plugins to add those. That said, I'm more than happy to talk about your needs and whether we could add support to make it easier for you (or any other platform) to perform those checks. |
Seems like a big implementation cost for relatively low benefit. Most of the time people never see component instances anyway. If there are specific places where we want to expose a component instance it's better, IMO, to go the other way. Define an interface for your non-template interaction and provide the component instance as that interface. This is much safer (when we need the safety) than the other approach of selectively hiding bits of the API |
Not true with APIs including injection and querying (
Doesn't help with the |
So there is another reason this would be really nice. For the M2 migration we need to keep API compatibility, but some of those APIs are just there for the template itself. It would be nice to mark them as such so that: |
Some changes to the above:
|
The first PRs have gone in. We are waiting for SDK support on dart-lang/sdk#33353 now. |
What is the implication for these getters being used in other templates by referencing a component with a template variable? Will that be discouraged or explicitly disallowed? dart-lang/sdk#33353 (comment) seems to indicate that the below would be valid. @Component(
selector: 'child',
template: 'Look, it's {{seeminglyPrivate}}!',
)
class ChildComponent {
@visibleForTemplate
final seeminglyPrivate = 'secrets';
}
// Far away
@Component(
selector: 'parent',
template: '''
<child #ref></child>
I have access to your {{ref.seeminglyPrivate}}!
'''
)
class ParentComponent {} |
Unfortunately, likely nothing - any file named // a.dart
@Component(
selector: 'a',
template: '<b [privateThing]="'Hello'"></b>',
directives: [B],
)
class A {} // b.dart
@Component(
selector: 'b',
template: 'Hello {{b}}!',
)
class B {
@visibleForTemplate
@Input('privateThing')
String b;
} ... would need the following code generated in _childCompB.b = 'Hello'; We could limit We could also introduce multiple annotations, i.e.:
I'm not sure this is worth its weight considering it is a static check only. For example, you could do: class ParentComp {
@visibleForTemplate
String doNotTouch;
}
class ChildComp {
ChildComp(ParentComp p) {
dynamic d = p;
d.doNotTouch = 'Hehe'!;
}
} (And this technique works for anything, i.e. We also could try to have the AngularDart Analyzer Plugin lint usages in /cc @nshahan @TedSander @MichaelRFairhurst on thoughts here. |
@zoechi: Please do not suggest the behavior of something without knowing what the answer is - in this case you were not correct. It is OK to have opinions, but it can be very confusing for readers and users if they read your message, and think it is correct, and then we have to back-track when that is not the case. |
Thanks for clarifying, @matanlurey. I agree: these cases are much less common. Maybe this case would be served well enough by additions to the style guide describing what should be considered part of a components public API vs what is expected to be private to the component's template? We're starting to get into more complicated territory, but regarding > 1 component per dart library, could something along the lines of: Part of me is inclined to say that if someone is casting to @Component(
selector: 'some-cmp',
template: '''
<child-cmp></child-cmp>
<child-cmp></child-cmp>
<child-cmp></child-cmp>
''',
directives: [ChildCmp],
)
class SomeCmp {
@ViewChildren(ChildCmp)
List children; // <------------- accidentally List<dynamic>
void doStuff() {
for (final child in children) {
child.public; // sure
child.privateToTemplate; // less good...
child.recentlyRemovedField; // yikes!
}
} |
That makes sense to me. If you have any ideas for what should be a starting point, start a PR (or even just an issue, if you'd like).
Yeah, that's possible. But as you mention it falls apart for inline templates. I wouldn't want 3 ways to do something :-/
That is my position as well. |
Thanks, @matanlurey. Started an issue for discussion of what the guidelines should be: #1509. |
As per @srawlins, this has landed in We will export and make the annotation available to end-users in the first release that supports that SDK. |
Closes #930. PiperOrigin-RevId: 212358660
This is a "hotly requested" feature from large internal clients.
/cc @MichaelRFairhurst for thoughts as well.
The text was updated successfully, but these errors were encountered: