Angular 2 изменения переменных компонента на другом компоненте
Как компонент может изменить переменную на другой компонент. Пример:
У меня есть компонент app.component.ts
@Component({
selector: 'my-app',
template: `
<nav *ngIf="onMain == false">
Hello
</nav>
`
})
export class AppComponent{
onMain: Boolean;
constructor(){
this.onMain = false;
}
}
У меня есть другой компонент, который я хочу изменить onMain в компоненте моего приложения main.component.ts
import {AppComponent} from '../app.component';
@Component({
selector: 'main-app',
template: ``
})
export class MainComponent{
constructor() {
this.appComponent = AppComponent;
this.appComponent.onMain = true;
}
}
Я бы ожидал, что Hello исчезнет, но это не так. Как я могу изменить один компонент на другой компонент?
Ответы
Ответ 1
Прежде всего, у вас нет связи между двумя компонентами или, может быть, что-то не так в вашем коде. Если у вас есть сценарий родителя/ребенка, вы можете использовать @Input,@Output
angular2. Если у вас нет родительского/дочернего сценария, вы можете пойти с EventEmitter,SharedService
из angular2.
Рабочий демон-путь EventEmitter
Я рассматривал AppComponent
как parentComponent и MainComponent как дочерний компонент. Используя SharedService & EventEmitter
понятия angular2
, я могу скрыть часть представления AppComponent's
, нажав кнопку, принадлежащую представлению "MainComponent".
AppComponent.ts
import {Component,bind,CORE_DIRECTIVES,OnInit} from 'angular2/core';
import {MainComponent} from 'src/MainComponent';
import {SharedService} from 'src/shared.service';
@Component({
selector: 'my-app',
directives:[MainComponent],
template: `<h1>AppComponent {{onMain}}</h1>
<div *ngIf="onMain == false">
Hello
<br> __________________________________<br>
</div>
<main-app></main-app>
`
})
export class AppComponent implements OnInit {
onMain: Boolean;
constructor(ss: SharedService) {
this.onMain = false;
this.ss = ss;
}
ngOnInit() {
this.subscription = this.ss.getEmittedValue()
.subscribe(item => this.onMain=item);
}
}
MainComponent.ts
import {Component,bind,CORE_DIRECTIVES} from 'angular2/core';
import {SharedService} from 'src/shared.service';
@Component({
selector: 'main-app',
template: `<h1> MainComponent</h1>
<button (click)="changeName()">Change Name</button>
`
})
export class MainComponent {
constructor(ss: SharedService) {
this.ss = ss;
}
changeName() {
this.ss.change();
}
}
shared.service.ts
import {Component, Injectable,Input,Output,EventEmitter} from 'angular2/core'
@Injectable()
export class SharedService {
@Output() fire: EventEmitter<any> = new EventEmitter();
constructor() {
console.log('shared service started');
}
change() {
console.log('change started');
this.fire.emit(true);
}
getEmittedValue() {
return this.fire;
}
}
Ответ 2
Если между компонентами (я имею в виду parent/child) нет отношения, вам необходимо использовать общую службу с свойством EventEmitter
. Один компонент будет генерировать событие, основанное на нем, и этот другой компонент будет уведомлен, подписав EventEmitter
. Когда событие получено, этот компонент может установить свойство, используемое для отображения/скрытия кнопки...
-
Общая служба
@Injectable()
export class SharedService {
onMainEvent: EventEmitter = new EventEmitter();
}
Не забудьте определить соответствующего провайдера в функции boostrap, чтобы иметь возможность использовать один и тот же экземпляр службы для всего приложения: `bootstrap (AppComponent, [SharedService]);
-
AppComponent
Компонент
@Component({ ... })
export class AppComponent {
onMain: boolean = false;
constructor(service: MenuService) {
sharedService.onMainEvent.subscribe(
(onMain) => {
this.onMain = onMain;
}
);
}
}
-
MainComponent
:
export class MainComponent {
constructor(private service: SharedService) {
}
updateOnMain(onMain):void {
this.service.onMainEvent.emit(onMain);
}
}
Эти вопросы для более подробной информации:
Ответ 3
Да, вы можете изменить значение переменной с одного компонента на другое, для этого вам нужно
inject
компонент экспортировал класс в родительский компонент, сделав так
вы можете использовать каждый метод и переменную вводимого класса (компонента).
import {Component} from 'angular2/core';
@Component({
selector: 'my-app',
templateUrl: `myTemplate.html`,
directive: [AppComponent2]
})
export class AppComponent {
variable1: boolean = true;
}
@Component({
selector: 'my-app2',
templateUrl: `temp2.html`,
providers: [AppComponent]
})
export class AppComponent2 {
constructor(private appComponent: AppComponent){ }
Fun(){
console.log('Function Called');
this.appComponent.variable1 = false;
}
}
<button (click)='Fun()'>Change Variable</button>
{{appComponent.variable1}}
Рабочий пример http://plnkr.co/edit/fpYFueOnkm5sa4JfG7uX?p=preview
Ответ 4
Если у вас есть отношения между родителями и дочерними элементами, вы можете использовать излучатель событий, чтобы перевернуть переменную только с помощью пары строк кода. Нет необходимости писать целую общую службу.
app.component.ts
@Component({
selector: 'my-app',
template: `
<nav *ngIf="onMain == false" (observableEvent)="onMain == true">
Hello
</nav>
`
})
main.component.ts
import {AppComponent} from '../app.component';
import { Output, EventEmitter } from '@angular/core';
@Component({
selector: 'main-app',
template: ``
})
export class MainComponent{
@Output() observableEvent: EventEmitter<any> = new EventEmitter<any>();
constructor() {
this.appComponent = AppComponent;
this.observableEvent.emit();
}
}