Подтвердить что ты не робот

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 исчезнет, ​​но это не так. Как я могу изменить один компонент на другой компонент?

4b9b3361

Ответ 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();
    }
}