最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Sending action to parent component Angular2 - Stack Overflow

programmeradmin7浏览0评论

I have 2 ponents one is a Topbar and the second is a Display here they are:

Display:

import {Component, View, NgIf} from 'angular2/angular2';

import {Topbar} from '../topbar/topbar';

@Component({
  selector: 'display'
})
@View({
  templateUrl: './ponents/display/display.html',
  styleUrls: ['./ponents/display/display.css'],
  directives: [Topbar, NgIf]
})

export class Display {
    showGrid: boolean;

    constructor(){
        this.showGrid = true;
    }
}

Display HTML(important for my issue):

<topbar></topbar>
<div *ng-if="showGrid" class="display-list">
    <h1>true</h1>
</div>
<div *ng-if="showGrid == false" class="display-list">
    <h1>false</h1>
</div>

As you can see I have an if statement depending on the showGrid property. Now here is my Topbar ponent:

Topbar:

import {Component, View} from 'angular2/angular2';
import {ROUTER_DIRECTIVES} from 'angular2/router';

@Component({
  selector: 'topbar'
})
@View({
  templateUrl: './ponents/topbar/topbar.html',
  styleUrls: ['./ponents/topbar/topbar.css'],
  directives: [ROUTER_DIRECTIVES]
})
export class Topbar {
  toggleGrid(){
    // update Display showGrid property
  }
}

Topbar HTML:

<div (click)="toggleGrid()" class="col-md-1 no-padding grid-toggle">
  <img src="assets/imgs/icons/icon-list.svg">
</div>

As you can see I have a function toggleGrid this function is to toggle the Display property showGrid; however, I can't seem to find a way to get this done. Since Topbar is a directive of Display I can't inject Display into Topbar. I've tried creating a service but the issue with this is that it doesn't update the Display showGrid property

I have 2 ponents one is a Topbar and the second is a Display here they are:

Display:

import {Component, View, NgIf} from 'angular2/angular2';

import {Topbar} from '../topbar/topbar';

@Component({
  selector: 'display'
})
@View({
  templateUrl: './ponents/display/display.html',
  styleUrls: ['./ponents/display/display.css'],
  directives: [Topbar, NgIf]
})

export class Display {
    showGrid: boolean;

    constructor(){
        this.showGrid = true;
    }
}

Display HTML(important for my issue):

<topbar></topbar>
<div *ng-if="showGrid" class="display-list">
    <h1>true</h1>
</div>
<div *ng-if="showGrid == false" class="display-list">
    <h1>false</h1>
</div>

As you can see I have an if statement depending on the showGrid property. Now here is my Topbar ponent:

Topbar:

import {Component, View} from 'angular2/angular2';
import {ROUTER_DIRECTIVES} from 'angular2/router';

@Component({
  selector: 'topbar'
})
@View({
  templateUrl: './ponents/topbar/topbar.html',
  styleUrls: ['./ponents/topbar/topbar.css'],
  directives: [ROUTER_DIRECTIVES]
})
export class Topbar {
  toggleGrid(){
    // update Display showGrid property
  }
}

Topbar HTML:

<div (click)="toggleGrid()" class="col-md-1 no-padding grid-toggle">
  <img src="assets/imgs/icons/icon-list.svg">
</div>

As you can see I have a function toggleGrid this function is to toggle the Display property showGrid; however, I can't seem to find a way to get this done. Since Topbar is a directive of Display I can't inject Display into Topbar. I've tried creating a service but the issue with this is that it doesn't update the Display showGrid property

Share Improve this question edited Dec 13, 2017 at 11:12 Freego 4667 silver badges18 bronze badges asked Oct 13, 2015 at 20:23 ThreeAccentsThreeAccents 1,8822 gold badges16 silver badges25 bronze badges 2
  • Don't you have a design issue? I would treat topbar and display as siblings and use them in a parent ponent. – lame_coder Commented Oct 14, 2015 at 0:24
  • Display is Topbar's parent, so yes, you can inject it using @Host() – Eric Martinez Commented Oct 14, 2015 at 3:19
Add a ment  | 

1 Answer 1

Reset to default 8

There is two approaches:

1.

You just need to define some toggle-grid event (output property) for your <toolbar> ponent and then listen to it in your Display ponent. See this plunker.

@Component({
  selector: 'topbar'
})
@View({
  template: `
    <div (click)="onButtonClick()">
      Button
    </div>
  `
})
export class Topbar {
  @Output() toggleGrid = new EventEmitter();

  onButtonClick() {
    this.toggleGrid.next();
  }
}

@Component({
  selector: 'display'
})
@View({
  directives: [Topbar, NgIf],
  template: `
    <topbar (toggle-grid)="toggleGrid()"></topbar>
    <div *ng-if="showGrid" class="display-list">
        <h1>true</h1>
    </div>
    <div *ng-if="showGrid == false" class="display-list">
        <h1>false</h1>
    </div>
  `
})
export class Display {
    showGrid: boolean = true;

    toggleGrid() {
      this.showGrid = !this.showGrid;
    }
}

2.

Use @Host and maybe forwardRef to inject parent ponent into child. See this plunker

@Component({
  selector: 'topbar'
})
@View({
  template: `
    <div (click)="onButtonClick()">
      Button
    </div>
  `
})
export class Topbar {
  display: Display;

  constructor(@Host() @Inject(forwardRef(() => Display)) display: Display) {
    this.display = display;
  }

  onButtonClick() {
    this.display.toggleGrid()
  }
}

@Component({
  selector: 'display'
})
@View({
  directives: [Topbar, NgIf],
  template: `
    <topbar></topbar>
    <div *ng-if="showGrid" class="display-list">
        <h1>true</h1>
    </div>
    <div *ng-if="showGrid == false" class="display-list">
        <h1>false</h1>
    </div>
  `
})
export class Display {
    showGrid: boolean = true;

    toggleGrid() {
      this.showGrid = !this.showGrid;
    }
}

Personally, I much prefer the first approach as it makes data flow of your application to be more explicit.

发布评论

评论列表(0)

  1. 暂无评论