Angular 2 Dart:如何在带有路由的父组件和子组件之间共享变量?
Angular 2 Dart: How to share variables between parent with router and child components?
如果有一个带有路由器的子组件并通过绑定更新它们,我该如何共享变量?
这是我的(部分)代码:
app_component.dart:
import 'package:angular2/core.dart';
import 'package:angular2_components/angular2_components.dart';
import 'package:angular2/router.dart';
import 'package:my_app/profile_component/profile_component.dart';
import 'package:my_app/login_component/login_component.dart';
@Component(
selector: 'my-app',
styleUrls: const ['app_component.css'],
templateUrl: 'app_component.html',
directives: const [
ROUTER_DIRECTIVES,
materialDirectives,
LoginComponent,
ProfileComponent
],
providers: const [
ROUTER_PROVIDERS,
const Provider(LocationStrategy, useClass: HashLocationStrategy),
materialProviders
],
)
@RouteConfig(const [
const Route(path: 'home', name: 'Home', component: HomeComponent, useAsDefault: true),
const Route(path: 'profile', name: "User Profile", component: ProfileComponent)
])
class AppComponent {
@ViewChild('login')
LoginComponent loginComponent;
@ViewChild('profile')
ProfileComponent profileComponent;
bool get isUserLoggedIn => loginComponent.isUserLoggedIn;
}
app_component.html:
<nav>
<ul>
<li *ngIf="!isUserLoggedIn">
<a (click)="loginComponent.loginOpen=true">Account / Login</a>
</li>
<li *ngIf="isUserLoggedIn">
<a id="mb_logout" (click)="loginComponent.logUserOut()">Logout</a>
</li>
<li *ngIf="isUserLoggedIn">
<a id="mb_profile" [routerLink]="['User Profile']">Zum Profil</a>
</li>
</ul>
</nav>
login_component.dart:
...
bool get isUserLoggedIn => _isUserLoggedIn();
...
profile_component.dart:
import 'package:angular2/core.dart';
import 'package:angular2_components/angular2_components.dart';
@Component(
selector: 'profile',
styleUrls: const ['profile_component.css'],
templateUrl: 'profile_component.html',
directives: const [materialDirectives],
providers: const [materialProviders],
)
class ProfileComponent {
@Input()
bool isUserLoggedIn;
ProfileComponent() {
print(isUserLoggedIn);
}
}
简而言之,我想从 ProfileComponent 中访问 isUserLoggedIn 的当前值。我怎样才能做到这一点?
我就是这样实现的。使用共享服务。
在模型所在的组件中 updated/used:
class myClassSend {
constructor(private sharedService: SharedService){
this.sharedService.userStatusUpdate(this.isUserLoggedIn); // We send isUserLoggedIn value to the shared service
}
}
我们的共享服务可能是这样的:
export class SharedService {
userStatusUpdate$: Observable<any>;
private userStatusUpdateSubject = new Subject<any>();
constructor() {
this.userStatusUpdate$ = this.userStatusUpdateSubject.asObservable();
}
userStatusUpdate(userStatus) {
this.userStatusUpdateSubject.next(userStatus);
}
}
在我们想知道模型值的组件中:
class myClassReceive {
bool isUserLoggedIn;
constructor(private sharedService: SharedService){
this.sharedService.userStatusUpdate$.subscribe((userStatus) => {
this.isUserLoggedIn = userStatus; // And here we receive the isUserLoggedIn value!
}
);
}
现在,认为从 myClassSend
开始,您可以随时发送信息:onInit、onChange 等...而 myClassReceive
将是 "listening" 始终接收您作为参数发送到共享服务的值。
将共享服务视为一个单元 phone,它与 2 个人(组件)进行通信,发送消息 (parameters/data)。
这是 Angular 的文档:https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
在父组件上提供共享服务
@Injectable()
class SharedService {
bool _isUserLoggedIn = false;
bool get isUserLoggedIn => _isUserLoggedIn;
set isUserLoggedIn(bool value) {
_isUserLoggedIn = value ?? false;
_isUserLoggedInController.add(_isUserLoggedIn);
}
StreamController<bool> _isUserLoggedInController;
Stream<bool> get onIsUserLoggedIn => _isUserLoggedInController.stream;
SharedService() {
_isUserLoggedInController = new StreamController<bool>.broadcast(
onListen: () => _isUserLoggedInController.add(_isUserLoggedIn)
);
}
}
在要更新的组件中使用或更新状态注入服务
@Component(
...,
template: '''
<div>isLoggedIn: {{sharedService.onIsUserLoggedIn | async}}</div>
<button (click)="toggleIsUserLoggedIn()">{{(sharedService.onIsUserLoggedIn | async) ? 'log out' : 'log in'}}</div>
''',
)
class SomeComponent {
final SharedService sharedService;
SomeComponent(this.sharedService);
toggleIsUserLoggedIn() {
sharedService.isUserLoggedIn = !sharedService.isUserLoggedIn;
}
}
在AppComponent
提供服务
@Component(
selector: 'my-app',
providers: const [SharedService],
)
class AppComponent {}
如果有一个带有路由器的子组件并通过绑定更新它们,我该如何共享变量?
这是我的(部分)代码:
app_component.dart:
import 'package:angular2/core.dart';
import 'package:angular2_components/angular2_components.dart';
import 'package:angular2/router.dart';
import 'package:my_app/profile_component/profile_component.dart';
import 'package:my_app/login_component/login_component.dart';
@Component(
selector: 'my-app',
styleUrls: const ['app_component.css'],
templateUrl: 'app_component.html',
directives: const [
ROUTER_DIRECTIVES,
materialDirectives,
LoginComponent,
ProfileComponent
],
providers: const [
ROUTER_PROVIDERS,
const Provider(LocationStrategy, useClass: HashLocationStrategy),
materialProviders
],
)
@RouteConfig(const [
const Route(path: 'home', name: 'Home', component: HomeComponent, useAsDefault: true),
const Route(path: 'profile', name: "User Profile", component: ProfileComponent)
])
class AppComponent {
@ViewChild('login')
LoginComponent loginComponent;
@ViewChild('profile')
ProfileComponent profileComponent;
bool get isUserLoggedIn => loginComponent.isUserLoggedIn;
}
app_component.html:
<nav>
<ul>
<li *ngIf="!isUserLoggedIn">
<a (click)="loginComponent.loginOpen=true">Account / Login</a>
</li>
<li *ngIf="isUserLoggedIn">
<a id="mb_logout" (click)="loginComponent.logUserOut()">Logout</a>
</li>
<li *ngIf="isUserLoggedIn">
<a id="mb_profile" [routerLink]="['User Profile']">Zum Profil</a>
</li>
</ul>
</nav>
login_component.dart:
...
bool get isUserLoggedIn => _isUserLoggedIn();
...
profile_component.dart:
import 'package:angular2/core.dart';
import 'package:angular2_components/angular2_components.dart';
@Component(
selector: 'profile',
styleUrls: const ['profile_component.css'],
templateUrl: 'profile_component.html',
directives: const [materialDirectives],
providers: const [materialProviders],
)
class ProfileComponent {
@Input()
bool isUserLoggedIn;
ProfileComponent() {
print(isUserLoggedIn);
}
}
简而言之,我想从 ProfileComponent 中访问 isUserLoggedIn 的当前值。我怎样才能做到这一点?
我就是这样实现的。使用共享服务。
在模型所在的组件中 updated/used:
class myClassSend {
constructor(private sharedService: SharedService){
this.sharedService.userStatusUpdate(this.isUserLoggedIn); // We send isUserLoggedIn value to the shared service
}
}
我们的共享服务可能是这样的:
export class SharedService {
userStatusUpdate$: Observable<any>;
private userStatusUpdateSubject = new Subject<any>();
constructor() {
this.userStatusUpdate$ = this.userStatusUpdateSubject.asObservable();
}
userStatusUpdate(userStatus) {
this.userStatusUpdateSubject.next(userStatus);
}
}
在我们想知道模型值的组件中:
class myClassReceive {
bool isUserLoggedIn;
constructor(private sharedService: SharedService){
this.sharedService.userStatusUpdate$.subscribe((userStatus) => {
this.isUserLoggedIn = userStatus; // And here we receive the isUserLoggedIn value!
}
);
}
现在,认为从 myClassSend
开始,您可以随时发送信息:onInit、onChange 等...而 myClassReceive
将是 "listening" 始终接收您作为参数发送到共享服务的值。
将共享服务视为一个单元 phone,它与 2 个人(组件)进行通信,发送消息 (parameters/data)。
这是 Angular 的文档:https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
在父组件上提供共享服务
@Injectable()
class SharedService {
bool _isUserLoggedIn = false;
bool get isUserLoggedIn => _isUserLoggedIn;
set isUserLoggedIn(bool value) {
_isUserLoggedIn = value ?? false;
_isUserLoggedInController.add(_isUserLoggedIn);
}
StreamController<bool> _isUserLoggedInController;
Stream<bool> get onIsUserLoggedIn => _isUserLoggedInController.stream;
SharedService() {
_isUserLoggedInController = new StreamController<bool>.broadcast(
onListen: () => _isUserLoggedInController.add(_isUserLoggedIn)
);
}
}
在要更新的组件中使用或更新状态注入服务
@Component(
...,
template: '''
<div>isLoggedIn: {{sharedService.onIsUserLoggedIn | async}}</div>
<button (click)="toggleIsUserLoggedIn()">{{(sharedService.onIsUserLoggedIn | async) ? 'log out' : 'log in'}}</div>
''',
)
class SomeComponent {
final SharedService sharedService;
SomeComponent(this.sharedService);
toggleIsUserLoggedIn() {
sharedService.isUserLoggedIn = !sharedService.isUserLoggedIn;
}
}
在AppComponent
@Component(
selector: 'my-app',
providers: const [SharedService],
)
class AppComponent {}