This repository has been archived by the owner on Sep 16, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 232
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature(templates): Support event tearoffs in AngularDart templates.
Closes #1437 PiperOrigin-RevId: 202550856
- Loading branch information
1 parent
c562ea9
commit d72bcef
Showing
9 changed files
with
295 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import 'package:angular/angular.dart'; | ||
|
||
@Component( | ||
selector: 'uses-event-tearoff', | ||
template: r''' | ||
<button (click)="onClick" (blur)="onBlur"></button> | ||
''', | ||
) | ||
class UsesEventTearoff { | ||
void onClick(Object e) {} | ||
|
||
void onBlur() {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// ignore_for_file: library_prefixes,unused_import,no_default_super_constructor_explicit,duplicate_import,unused_shown_name | ||
// The .template.dart files also export the user code. | ||
export 'event_tearoff.dart'; | ||
|
||
// Required for referencing runtime code. | ||
import 'dart:html'; | ||
import 'package:angular/angular.dart'; | ||
import 'package:angular/src/core/change_detection/directive_change_detector.dart'; | ||
import 'package:angular/src/core/linker/app_view.dart'; | ||
|
||
// Required for specifically referencing user code. | ||
import 'event_tearoff.dart' as _user; | ||
|
||
// Required for "type inference" (scoping). | ||
import 'package:angular/angular.dart'; | ||
|
||
// For @Component class UsesEventTearoff. | ||
external List<dynamic> get styles$UsesEventTearoff; | ||
external ComponentFactory<_user.UsesEventTearoff> get UsesEventTearoffNgFactory; | ||
external AppView<_user.UsesEventTearoff> viewFactory_UsesEventTearoff0(AppView<dynamic> parentView, int parentIndex); | ||
class ViewUsesEventTearoff0 extends AppView<_user.UsesEventTearoff> { | ||
external ViewUsesEventTearoff0(AppView<dynamic> parentView, int parentIndex); | ||
} | ||
|
||
external void initReflector(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// ************************************************************************** | ||
// Generator: Instance of 'Compiler' | ||
// ************************************************************************** | ||
|
||
// ignore_for_file: cancel_subscriptions,constant_identifier_names,duplicate_import,non_constant_identifier_names,library_prefixes,UNUSED_IMPORT,UNUSED_SHOWN_NAME | ||
import 'event_tearoff.dart'; | ||
export 'event_tearoff.dart'; | ||
import 'package:angular/angular.dart'; | ||
import 'package:angular/src/di/reflector.dart' as _ngRef; | ||
import 'package:angular/angular.template.dart' as _ref0; | ||
import 'package:angular/src/core/linker/app_view.dart'; | ||
import 'event_tearoff.dart' as import1; | ||
import 'dart:html' as import2; | ||
import 'package:angular/src/core/render/api.dart'; | ||
import 'package:angular/src/core/linker/view_type.dart' as import4; | ||
import 'package:angular/src/core/change_detection/change_detection.dart'; | ||
import 'package:angular/src/core/linker/app_view_utils.dart' as import6; | ||
import 'package:angular/src/runtime.dart' as import7; | ||
import 'package:angular/angular.dart'; | ||
|
||
final List<dynamic> styles$UsesEventTearoff = const []; | ||
|
||
class ViewUsesEventTearoff0 extends AppView<import1.UsesEventTearoff> { | ||
import2.ButtonElement _el_0; | ||
static RenderComponentType _renderType; | ||
ViewUsesEventTearoff0(AppView<dynamic> parentView, int parentIndex) : super(import4.ViewType.component, {}, parentView, parentIndex, ChangeDetectionStrategy.CheckAlways) { | ||
rootEl = import2.document.createElement('uses-event-tearoff'); | ||
_renderType ??= import6.appViewUtils.createRenderType((import7.isDevMode ? 'asset:_goldens/test/_files/event_tearoff.dart' : null), ViewEncapsulation.None, styles$UsesEventTearoff); | ||
setupComponentType(_renderType); | ||
} | ||
@override | ||
ComponentRef<import1.UsesEventTearoff> build() { | ||
final _rootEl = rootEl; | ||
final import2.HtmlElement parentRenderNode = initViewRoot(_rootEl); | ||
var doc = import2.document; | ||
_el_0 = createAndAppend(doc, 'button', parentRenderNode); | ||
_el_0.addEventListener('click', eventHandler1(ctx.onClick)); | ||
_el_0.addEventListener('blur', eventHandler0(ctx.onBlur)); | ||
init(const [], null); | ||
return null; | ||
} | ||
} | ||
|
||
AppView<import1.UsesEventTearoff> viewFactory_UsesEventTearoff0(AppView<dynamic> parentView, int parentIndex) { | ||
return new ViewUsesEventTearoff0(parentView, parentIndex); | ||
} | ||
|
||
final List<dynamic> styles$UsesEventTearoffHost = const []; | ||
|
||
class _ViewUsesEventTearoffHost0 extends AppView<import1.UsesEventTearoff> { | ||
ViewUsesEventTearoff0 _compView_0; | ||
import1.UsesEventTearoff _UsesEventTearoff_0_5; | ||
_ViewUsesEventTearoffHost0(AppView<dynamic> parentView, int parentIndex) : super(import4.ViewType.host, {}, parentView, parentIndex, ChangeDetectionStrategy.CheckAlways); | ||
@override | ||
ComponentRef<import1.UsesEventTearoff> build() { | ||
_compView_0 = new ViewUsesEventTearoff0(this, 0); | ||
rootEl = _compView_0.rootEl; | ||
_UsesEventTearoff_0_5 = new import1.UsesEventTearoff(); | ||
_compView_0.create(_UsesEventTearoff_0_5, projectableNodes); | ||
init0(rootEl); | ||
return new ComponentRef(0, this, rootEl, _UsesEventTearoff_0_5); | ||
} | ||
|
||
@override | ||
void detectChangesInternal() { | ||
_compView_0.detectChanges(); | ||
} | ||
|
||
@override | ||
void destroyInternal() { | ||
_compView_0?.destroy(); | ||
} | ||
} | ||
|
||
AppView<import1.UsesEventTearoff> viewFactory_UsesEventTearoffHost0(AppView<dynamic> parentView, int parentIndex) { | ||
return new _ViewUsesEventTearoffHost0(parentView, parentIndex); | ||
} | ||
|
||
const ComponentFactory<import1.UsesEventTearoff> _UsesEventTearoffNgFactory = const ComponentFactory('uses-event-tearoff', viewFactory_UsesEventTearoffHost0, _UsesEventTearoffMetadata); | ||
ComponentFactory<import1.UsesEventTearoff> get UsesEventTearoffNgFactory { | ||
return _UsesEventTearoffNgFactory; | ||
} | ||
|
||
const _UsesEventTearoffMetadata = const []; | ||
var _visited = false; | ||
void initReflector() { | ||
if (_visited) { | ||
return; | ||
} | ||
_visited = true; | ||
|
||
_ngRef.registerComponent(UsesEventTearoff, UsesEventTearoffNgFactory); | ||
_ref0.initReflector(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
@TestOn('browser') | ||
import 'dart:async'; | ||
import 'dart:html'; | ||
|
||
import 'package:angular/angular.dart'; | ||
import 'package:angular_test/angular_test.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
import 'event_handler_test.template.dart' as ng; | ||
|
||
void main() { | ||
tearDown(disposeAnyRunningTest); | ||
|
||
NgTestFixture<ClickHandler> fixture; | ||
|
||
group('Event handler', () { | ||
setUp(() async { | ||
final testBed = NgTestBed.forComponent(ng.ClickHandlerNgFactory); | ||
fixture = await testBed.create(); | ||
}); | ||
|
||
group('method call', () { | ||
test('should handle click with no args', () async { | ||
fixture.update((cmp) => cmp.noArgButton.click()); | ||
expect(fixture.assertOnlyInstance.clicks, emits(null)); | ||
}); | ||
|
||
test('should handle click with one arg', () async { | ||
fixture.update((cmp) => cmp.oneArgButton.click()); | ||
expect(fixture.assertOnlyInstance.clicks, emits(null)); | ||
}); | ||
}); | ||
|
||
group('tearoffs', () { | ||
test('should handle click with no args', () async { | ||
fixture.update((cmp) => cmp.noArgTearoffButton.click()); | ||
expect(fixture.assertOnlyInstance.clicks, emits(null)); | ||
}); | ||
|
||
test('should handle click with one arg', () async { | ||
fixture.update((cmp) => cmp.oneArgTearoffButton.click()); | ||
expect(fixture.assertOnlyInstance.clicks, emits(null)); | ||
}); | ||
}); | ||
}); | ||
} | ||
|
||
@Component( | ||
selector: 'test', | ||
template: ''' | ||
<button #noArg (click)="onClick()"></button> | ||
<button #oneArg (click)="clickWithEvent(\$event)"></button> | ||
<button #noArgTearoff (click)="onClick"></button> | ||
<button #oneArgTearoff (click)="clickWithEvent"></button> | ||
''', | ||
) | ||
class ClickHandler { | ||
@ViewChild('noArg') | ||
HtmlElement noArgButton; | ||
|
||
@ViewChild('oneArg') | ||
HtmlElement oneArgButton; | ||
|
||
@ViewChild('noArgTearoff') | ||
HtmlElement noArgTearoffButton; | ||
|
||
@ViewChild('oneArgTearoff') | ||
HtmlElement oneArgTearoffButton; | ||
|
||
void onClick() { | ||
_clicks.add(null); | ||
} | ||
|
||
void clickWithEvent(Object event) { | ||
if (event != null) _clicks.add(null); | ||
} | ||
|
||
Stream get clicks => _clicks.stream; | ||
|
||
final StreamController _clicks = new StreamController(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.