@ -24,7 +24,6 @@ export class Instruction {
|
||||
// "capturedUrl" is the part of the URL captured by this instruction
|
||||
// "accumulatedUrl" is the part of the URL captured by this instruction and all children
|
||||
accumulatedUrl: string;
|
||||
|
||||
reuse: boolean = false;
|
||||
specificity: number;
|
||||
|
||||
@ -50,23 +49,4 @@ export class Instruction {
|
||||
}
|
||||
return this._params;
|
||||
}
|
||||
|
||||
hasChild(): boolean { return isPresent(this.child); }
|
||||
|
||||
/**
|
||||
* Takes a currently active instruction and sets a reuse flag on each of this instruction's
|
||||
* children
|
||||
*/
|
||||
reuseComponentsFrom(oldInstruction: Instruction): void {
|
||||
var nextInstruction = this;
|
||||
while (nextInstruction.reuse = shouldReuseComponent(nextInstruction, oldInstruction) &&
|
||||
isPresent(oldInstruction = oldInstruction.child) &&
|
||||
isPresent(nextInstruction = nextInstruction.child))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
function shouldReuseComponent(instr1: Instruction, instr2: Instruction): boolean {
|
||||
return instr1.component == instr2.component &&
|
||||
StringMapWrapper.equals(instr1.params(), instr2.params());
|
||||
}
|
||||
|
43
modules/angular2/src/router/interfaces.ts
Normal file
43
modules/angular2/src/router/interfaces.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import {Instruction} from './instruction';
|
||||
import {global} from 'angular2/src/facade/lang';
|
||||
|
||||
// This is here only so that after TS transpilation the file is not empty.
|
||||
// TODO(rado): find a better way to fix this, or remove if likely culprit
|
||||
// https://github.com/systemjs/systemjs/issues/487 gets closed.
|
||||
var __ignore_me = global;
|
||||
|
||||
|
||||
/**
|
||||
* Defines route lifecycle method [onActivate]
|
||||
*/
|
||||
export interface OnActivate {
|
||||
onActivate(nextInstruction: Instruction, prevInstruction: Instruction): any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines route lifecycle method [onReuse]
|
||||
*/
|
||||
export interface OnReuse {
|
||||
onReuse(nextInstruction: Instruction, prevInstruction: Instruction): any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines route lifecycle method [onDeactivate]
|
||||
*/
|
||||
export interface OnDeactivate {
|
||||
onDeactivate(nextInstruction: Instruction, prevInstruction: Instruction): any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines route lifecycle method [canReuse]
|
||||
*/
|
||||
export interface CanReuse {
|
||||
canReuse(nextInstruction: Instruction, prevInstruction: Instruction): any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines route lifecycle method [canDeactivate]
|
||||
*/
|
||||
export interface CanDeactivate {
|
||||
canDeactivate(nextInstruction: Instruction, prevInstruction: Instruction): any;
|
||||
}
|
8
modules/angular2/src/router/lifecycle_annotations.dart
Normal file
8
modules/angular2/src/router/lifecycle_annotations.dart
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* This indirection is needed for TS compilation path.
|
||||
* See comment in lifecycle_annotations.ts.
|
||||
*/
|
||||
|
||||
library angular2.router.lifecycle_annotations;
|
||||
|
||||
export "./lifecycle_annotations_impl.dart";
|
17
modules/angular2/src/router/lifecycle_annotations.ts
Normal file
17
modules/angular2/src/router/lifecycle_annotations.ts
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* This indirection is needed to free up Component, etc symbols in the public API
|
||||
* to be used by the decorator versions of these annotations.
|
||||
*/
|
||||
|
||||
import {makeDecorator} from 'angular2/src/util/decorators';
|
||||
import {CanActivate as CanActivateAnnotation} from './lifecycle_annotations_impl';
|
||||
|
||||
export {
|
||||
canReuse,
|
||||
canDeactivate,
|
||||
onActivate,
|
||||
onReuse,
|
||||
onDeactivate
|
||||
} from './lifecycle_annotations_impl';
|
||||
|
||||
export var CanActivate = makeDecorator(CanActivateAnnotation);
|
18
modules/angular2/src/router/lifecycle_annotations_impl.ts
Normal file
18
modules/angular2/src/router/lifecycle_annotations_impl.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import {CONST, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||
|
||||
@CONST()
|
||||
export class RouteLifecycleHook {
|
||||
constructor(public name: string) {}
|
||||
}
|
||||
|
||||
@CONST()
|
||||
export class CanActivate {
|
||||
constructor(public fn: Function) {}
|
||||
}
|
||||
|
||||
export const canReuse: RouteLifecycleHook = CONST_EXPR(new RouteLifecycleHook("canReuse"));
|
||||
export const canDeactivate: RouteLifecycleHook =
|
||||
CONST_EXPR(new RouteLifecycleHook("canDeactivate"));
|
||||
export const onActivate: RouteLifecycleHook = CONST_EXPR(new RouteLifecycleHook("onActivate"));
|
||||
export const onReuse: RouteLifecycleHook = CONST_EXPR(new RouteLifecycleHook("onReuse"));
|
||||
export const onDeactivate: RouteLifecycleHook = CONST_EXPR(new RouteLifecycleHook("onDeactivate"));
|
38
modules/angular2/src/router/route_lifecycle_reflector.dart
Normal file
38
modules/angular2/src/router/route_lifecycle_reflector.dart
Normal file
@ -0,0 +1,38 @@
|
||||
library angular.router.route_lifecycle_reflector;
|
||||
|
||||
import 'package:angular2/src/router/lifecycle_annotations_impl.dart';
|
||||
import 'package:angular2/src/router/interfaces.dart';
|
||||
import 'package:angular2/src/reflection/reflection.dart';
|
||||
|
||||
bool hasLifecycleHook(RouteLifecycleHook e, type) {
|
||||
if (type is! Type) return false;
|
||||
|
||||
final List interfaces = reflector.interfaces(type);
|
||||
var interface;
|
||||
|
||||
if (e == onActivate) {
|
||||
interface = OnActivate;
|
||||
} else if (e == onDeactivate) {
|
||||
interface = OnDeactivate;
|
||||
} else if (e == onReuse) {
|
||||
interface = OnReuse;
|
||||
} else if (e == canDeactivate) {
|
||||
interface = CanDeactivate;
|
||||
} else if (e == canReuse) {
|
||||
interface = CanReuse;
|
||||
}
|
||||
|
||||
return interfaces.contains(interface);
|
||||
}
|
||||
|
||||
Function getCanActivateHook(type) {
|
||||
final List annotations = reflector.annotations(type);
|
||||
|
||||
for (var annotation in annotations) {
|
||||
if (annotation is CanActivate) {
|
||||
return annotation.fn;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
20
modules/angular2/src/router/route_lifecycle_reflector.ts
Normal file
20
modules/angular2/src/router/route_lifecycle_reflector.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import {Type, isPresent} from 'angular2/src/facade/lang';
|
||||
import {RouteLifecycleHook, CanActivate} from './lifecycle_annotations_impl';
|
||||
import {reflector} from 'angular2/src/reflection/reflection';
|
||||
|
||||
export function hasLifecycleHook(e: RouteLifecycleHook, type): boolean {
|
||||
if (!(type instanceof Type)) return false;
|
||||
return e.name in(<any>type).prototype;
|
||||
}
|
||||
|
||||
export function getCanActivateHook(type): Function {
|
||||
var annotations = reflector.annotations(type);
|
||||
for (let i = 0; i < annotations.length; i += 1) {
|
||||
let annotation = annotations[i];
|
||||
if (annotation instanceof CanActivate) {
|
||||
return annotation.fn;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
@ -126,7 +126,11 @@ export class RouteRegistry {
|
||||
this.configFromComponent(componentType);
|
||||
|
||||
if (partialMatch.unmatchedUrl.length == 0) {
|
||||
return new Instruction(componentType, partialMatch.matchedUrl, recognizer);
|
||||
if (recognizer.terminal) {
|
||||
return new Instruction(componentType, partialMatch.matchedUrl, recognizer);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return this.recognize(partialMatch.unmatchedUrl, componentType)
|
||||
|
@ -15,6 +15,7 @@ import {Pipeline} from './pipeline';
|
||||
import {Instruction} from './instruction';
|
||||
import {RouterOutlet} from './router_outlet';
|
||||
import {Location} from './location';
|
||||
import {getCanActivateHook} from './route_lifecycle_reflector';
|
||||
|
||||
let _resolveToTrue = PromiseWrapper.resolve(true);
|
||||
let _resolveToFalse = PromiseWrapper.resolve(false);
|
||||
@ -39,7 +40,6 @@ let _resolveToFalse = PromiseWrapper.resolve(false);
|
||||
export class Router {
|
||||
navigating: boolean = false;
|
||||
lastNavigationAttempt: string;
|
||||
previousUrl: string = null;
|
||||
|
||||
private _currentInstruction: Instruction = null;
|
||||
private _currentNavigation: Promise<any> = _resolveToTrue;
|
||||
@ -67,7 +67,7 @@ export class Router {
|
||||
// TODO: sibling routes
|
||||
this._outlet = outlet;
|
||||
if (isPresent(this._currentInstruction)) {
|
||||
return outlet.activate(this._currentInstruction);
|
||||
return outlet.commit(this._currentInstruction);
|
||||
}
|
||||
return _resolveToTrue;
|
||||
}
|
||||
@ -109,35 +109,94 @@ export class Router {
|
||||
* If the given URL does not begin with `/`, the router will navigate relative to this component.
|
||||
*/
|
||||
navigate(url: string): Promise<any> {
|
||||
if (this.navigating) {
|
||||
return this._currentNavigation;
|
||||
}
|
||||
this.lastNavigationAttempt = url;
|
||||
return this._currentNavigation = this.recognize(url).then((matchedInstruction) => {
|
||||
if (isBlank(matchedInstruction)) {
|
||||
return _resolveToFalse;
|
||||
}
|
||||
|
||||
if (isPresent(this._currentInstruction)) {
|
||||
matchedInstruction.reuseComponentsFrom(this._currentInstruction);
|
||||
}
|
||||
|
||||
return this._currentNavigation = this._currentNavigation.then((_) => {
|
||||
this.lastNavigationAttempt = url;
|
||||
this._startNavigating();
|
||||
|
||||
var result =
|
||||
this.commit(matchedInstruction)
|
||||
.then((_) => {
|
||||
this._finishNavigating();
|
||||
ObservableWrapper.callNext(this._subject, matchedInstruction.accumulatedUrl);
|
||||
});
|
||||
|
||||
return PromiseWrapper.catchError(result, (err) => {
|
||||
this._finishNavigating();
|
||||
throw err;
|
||||
});
|
||||
return this._afterPromiseFinishNavigating(this.recognize(url).then((matchedInstruction) => {
|
||||
if (isBlank(matchedInstruction)) {
|
||||
return false;
|
||||
}
|
||||
return this._reuse(matchedInstruction)
|
||||
.then((_) => this._canActivate(matchedInstruction))
|
||||
.then((result) => {
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
return this._canDeactivate(matchedInstruction)
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
return this.commit(matchedInstruction)
|
||||
.then((_) => {
|
||||
this._emitNavigationFinish(matchedInstruction.accumulatedUrl);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
private _emitNavigationFinish(url): void { ObservableWrapper.callNext(this._subject, url); }
|
||||
|
||||
private _afterPromiseFinishNavigating(promise: Promise<any>): Promise<any> {
|
||||
return PromiseWrapper.catchError(promise.then((_) => this._finishNavigating()), (err) => {
|
||||
this._finishNavigating();
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
_reuse(instruction): Promise<any> {
|
||||
if (isBlank(this._outlet)) {
|
||||
return _resolveToFalse;
|
||||
}
|
||||
return this._outlet.canReuse(instruction)
|
||||
.then((result) => {
|
||||
instruction.reuse = result;
|
||||
if (isPresent(this._outlet.childRouter) && isPresent(instruction.child)) {
|
||||
return this._outlet.childRouter._reuse(instruction.child);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _canActivate(instruction: Instruction): Promise<boolean> {
|
||||
return canActivateOne(instruction, this._currentInstruction);
|
||||
}
|
||||
|
||||
private _canDeactivate(instruction: Instruction): Promise<boolean> {
|
||||
if (isBlank(this._outlet)) {
|
||||
return _resolveToTrue;
|
||||
}
|
||||
var next: Promise<boolean>;
|
||||
if (isPresent(instruction) && instruction.reuse) {
|
||||
next = _resolveToTrue;
|
||||
} else {
|
||||
next = this._outlet.canDeactivate(instruction);
|
||||
}
|
||||
return next.then((result) => {
|
||||
if (result == false) {
|
||||
return false;
|
||||
}
|
||||
if (isPresent(this._outlet.childRouter)) {
|
||||
return this._outlet.childRouter._canDeactivate(isPresent(instruction) ? instruction.child :
|
||||
null);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this router and all descendant routers according to the given instruction
|
||||
*/
|
||||
commit(instruction: Instruction): Promise<any> {
|
||||
this._currentInstruction = instruction;
|
||||
if (isPresent(this._outlet)) {
|
||||
return this._outlet.commit(instruction);
|
||||
}
|
||||
return _resolveToTrue;
|
||||
}
|
||||
|
||||
|
||||
_startNavigating(): void { this.navigating = true; }
|
||||
|
||||
_finishNavigating(): void { this.navigating = false; }
|
||||
@ -149,24 +208,12 @@ export class Router {
|
||||
subscribe(onNext): void { ObservableWrapper.subscribe(this._subject, onNext); }
|
||||
|
||||
|
||||
/**
|
||||
* Updates this router and all descendant routers according to the given instruction
|
||||
*/
|
||||
commit(instruction: Instruction): Promise<any> {
|
||||
this._currentInstruction = instruction;
|
||||
if (isPresent(this._outlet)) {
|
||||
return this._outlet.activate(instruction);
|
||||
}
|
||||
return _resolveToTrue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes the contents of this router's outlet and all descendant outlets
|
||||
*/
|
||||
deactivate(): Promise<any> {
|
||||
deactivate(instruction: Instruction): Promise<any> {
|
||||
if (isPresent(this._outlet)) {
|
||||
return this._outlet.deactivate();
|
||||
return this._outlet.deactivate(instruction);
|
||||
}
|
||||
return _resolveToTrue;
|
||||
}
|
||||
@ -185,11 +232,10 @@ export class Router {
|
||||
* router has yet to successfully navigate.
|
||||
*/
|
||||
renavigate(): Promise<any> {
|
||||
var destination = isBlank(this.previousUrl) ? this.lastNavigationAttempt : this.previousUrl;
|
||||
if (isBlank(destination)) {
|
||||
if (isBlank(this.lastNavigationAttempt)) {
|
||||
return this._currentNavigation;
|
||||
}
|
||||
return this.navigate(destination);
|
||||
return this.navigate(this.lastNavigationAttempt);
|
||||
}
|
||||
|
||||
|
||||
@ -288,3 +334,24 @@ function splitAndFlattenLinkParams(linkParams: List<any>): List<any> {
|
||||
return accumulation;
|
||||
}, []);
|
||||
}
|
||||
|
||||
function canActivateOne(nextInstruction, currentInstruction): Promise<boolean> {
|
||||
var next = _resolveToTrue;
|
||||
if (isPresent(nextInstruction.child)) {
|
||||
next = canActivateOne(nextInstruction.child,
|
||||
isPresent(currentInstruction) ? currentInstruction.child : null);
|
||||
}
|
||||
return next.then((res) => {
|
||||
if (res == false) {
|
||||
return false;
|
||||
}
|
||||
if (nextInstruction.reuse) {
|
||||
return true;
|
||||
}
|
||||
var hook = getCanActivateHook(nextInstruction.component);
|
||||
if (isPresent(hook)) {
|
||||
return hook(nextInstruction, currentInstruction);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
import {isBlank, isPresent} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Directive, Attribute} from 'angular2/src/core/annotations/decorators';
|
||||
@ -6,8 +7,9 @@ import {DynamicComponentLoader, ComponentRef, ElementRef} from 'angular2/core';
|
||||
import {Injector, bind, Dependency, undefinedValue} from 'angular2/di';
|
||||
|
||||
import * as routerMod from './router';
|
||||
import {Instruction, RouteParams} from './instruction'
|
||||
|
||||
import {Instruction, RouteParams} from './instruction';
|
||||
import * as hookMod from './lifecycle_annotations';
|
||||
import {hasLifecycleHook} from './route_lifecycle_reflector';
|
||||
|
||||
/**
|
||||
* A router outlet is a placeholder that Angular dynamically fills based on the application's route.
|
||||
@ -18,11 +20,10 @@ import {Instruction, RouteParams} from './instruction'
|
||||
* <router-outlet></router-outlet>
|
||||
* ```
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'router-outlet'
|
||||
})
|
||||
@Directive({selector: 'router-outlet'})
|
||||
export class RouterOutlet {
|
||||
private _childRouter: routerMod.Router = null;
|
||||
childRouter: routerMod.Router = null;
|
||||
|
||||
private _componentRef: ComponentRef = null;
|
||||
private _currentInstruction: Instruction = null;
|
||||
|
||||
@ -38,34 +39,100 @@ export class RouterOutlet {
|
||||
/**
|
||||
* Given an instruction, update the contents of this outlet.
|
||||
*/
|
||||
activate(instruction: Instruction): Promise<any> {
|
||||
// if we're able to reuse the component, we just have to pass along the instruction to the
|
||||
// component's router
|
||||
// so it can propagate changes to its children
|
||||
if ((instruction == this._currentInstruction || instruction.reuse) &&
|
||||
isPresent(this._childRouter)) {
|
||||
return this._childRouter.commit(instruction.child);
|
||||
commit(instruction: Instruction): Promise<any> {
|
||||
var next;
|
||||
if (instruction.reuse) {
|
||||
next = this._reuse(instruction);
|
||||
} else {
|
||||
next = this.deactivate(instruction).then((_) => this._activate(instruction));
|
||||
}
|
||||
return next.then((_) => this._commitChild(instruction));
|
||||
}
|
||||
|
||||
private _commitChild(instruction: Instruction): Promise<any> {
|
||||
if (isPresent(this.childRouter)) {
|
||||
return this.childRouter.commit(instruction.child);
|
||||
} else {
|
||||
return PromiseWrapper.resolve(true);
|
||||
}
|
||||
}
|
||||
|
||||
private _activate(instruction: Instruction): Promise<any> {
|
||||
var previousInstruction = this._currentInstruction;
|
||||
this._currentInstruction = instruction;
|
||||
this._childRouter = this._parentRouter.childRouter(instruction.component);
|
||||
var params = new RouteParams(instruction.params());
|
||||
var bindings = Injector.resolve(
|
||||
[bind(RouteParams).toValue(params), bind(routerMod.Router).toValue(this._childRouter)]);
|
||||
this.childRouter = this._parentRouter.childRouter(instruction.component);
|
||||
|
||||
return this.deactivate()
|
||||
.then((_) => this._loader.loadNextToLocation(instruction.component, this._elementRef,
|
||||
bindings))
|
||||
var bindings = Injector.resolve([
|
||||
bind(RouteParams)
|
||||
.toValue(new RouteParams(instruction.params())),
|
||||
bind(routerMod.Router).toValue(this.childRouter)
|
||||
]);
|
||||
return this._loader.loadNextToLocation(instruction.component, this._elementRef, bindings)
|
||||
.then((componentRef) => {
|
||||
this._componentRef = componentRef;
|
||||
return this._childRouter.commit(instruction.child);
|
||||
if (hasLifecycleHook(hookMod.onActivate, instruction.component)) {
|
||||
return this._componentRef.instance.onActivate(instruction, previousInstruction);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
deactivate(): Promise<any> {
|
||||
return (isPresent(this._childRouter) ? this._childRouter.deactivate() :
|
||||
PromiseWrapper.resolve(true))
|
||||
/**
|
||||
* Called by Router during recognition phase
|
||||
*/
|
||||
canDeactivate(nextInstruction: Instruction): Promise<boolean> {
|
||||
if (isBlank(this._currentInstruction)) {
|
||||
return PromiseWrapper.resolve(true);
|
||||
}
|
||||
if (hasLifecycleHook(hookMod.canDeactivate, this._currentInstruction.component)) {
|
||||
return PromiseWrapper.resolve(
|
||||
this._componentRef.instance.canDeactivate(nextInstruction, this._currentInstruction));
|
||||
}
|
||||
return PromiseWrapper.resolve(true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by Router during recognition phase
|
||||
*/
|
||||
canReuse(nextInstruction: Instruction): Promise<boolean> {
|
||||
var result;
|
||||
if (isBlank(this._currentInstruction) ||
|
||||
this._currentInstruction.component != nextInstruction.component) {
|
||||
result = false;
|
||||
} else if (hasLifecycleHook(hookMod.canReuse, this._currentInstruction.component)) {
|
||||
result = this._componentRef.instance.canReuse(nextInstruction, this._currentInstruction);
|
||||
} else {
|
||||
result = nextInstruction == this._currentInstruction ||
|
||||
StringMapWrapper.equals(nextInstruction.params(), this._currentInstruction.params());
|
||||
}
|
||||
return PromiseWrapper.resolve(result);
|
||||
}
|
||||
|
||||
|
||||
private _reuse(instruction): Promise<any> {
|
||||
var previousInstruction = this._currentInstruction;
|
||||
this._currentInstruction = instruction;
|
||||
return PromiseWrapper.resolve(
|
||||
hasLifecycleHook(hookMod.onReuse, this._currentInstruction.component) ?
|
||||
this._componentRef.instance.onReuse(instruction, previousInstruction) :
|
||||
true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
deactivate(nextInstruction: Instruction): Promise<any> {
|
||||
return (isPresent(this.childRouter) ?
|
||||
this.childRouter.deactivate(isPresent(nextInstruction) ? nextInstruction.child :
|
||||
null) :
|
||||
PromiseWrapper.resolve(true))
|
||||
.then((_) => {
|
||||
if (isPresent(this._componentRef) && isPresent(this._currentInstruction) &&
|
||||
hasLifecycleHook(hookMod.onDeactivate, this._currentInstruction.component)) {
|
||||
return this._componentRef.instance.onDeactivate(nextInstruction,
|
||||
this._currentInstruction);
|
||||
}
|
||||
})
|
||||
.then((_) => {
|
||||
if (isPresent(this._componentRef)) {
|
||||
this._componentRef.dispose();
|
||||
@ -73,9 +140,4 @@ export class RouterOutlet {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
canDeactivate(instruction: Instruction): Promise<boolean> {
|
||||
// TODO: how to get ahold of the component instance here?
|
||||
return PromiseWrapper.resolve(true);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user