29

There is a master-detail example on the angular2 site. I can't follow the pattern in my example below.

In my example I have three components (1) customershome (2) customers and (3) customerdetails. The customershome compose customers (master) and customerdetails (details). In the customers component, I can select a customer and the details of the customer should be displayed in the customerdetails component.

How can I do the one-way communication from the customers component to the customerdetails component?

<div style="display: flex;">
    <div style="width:25vw">
        <customers></customers>
    </div>
    <div style="width:75vw; margin:5px">
        <customerdetails></customerdetails>
    </div>
</div>
wonderful world
  • 10,969
  • 20
  • 97
  • 194
  • Are you suggesting exposing a *customer* property in the *customers* component and then use an *input* property of the same for the *customerdetails*? – wonderful world Nov 28 '15 at 01:51
  • I recommend communicating via bound objects. Maybe you have a details object on some customer object somewhere that you can bind to the detail component. I have a master detail scenario here that might illustrate the concept: http://www.syntaxsuccess.com/viewarticle/recursive-treeview-in-angular-2.0 It's a treeview where a tree node can be a master for multiple child nodes. Different components, but a related concept from what I can tell. – TGH Nov 28 '15 at 02:02
  • @TGH I went through your example. It's a good example for a parent component composing child components. But I think I may need a different composition in my master-detail example. This is due to I may have hundreds of customers and it's details (when the user select it) can be retrieved reactively only. – wonderful world Nov 28 '15 at 11:53

3 Answers3

31

Here's a simple app that uses a parent <customer-browser> component with <customer-list> and <customer-detail> subcomponents.

http://plnkr.co/edit/aEjlwIKKhcErWAnIhY3C?p=preview

The browser itself simply accepts an array of customers as an input, and has an internal selectedCustomer property.

The list component accepts the same list, and exposes a "selected" property, and emits a selectedChange output event. This syntax allows two way binding, and that gets bound to the parent's selectedCustomer property.

The detail component simply takes an customer input which is bound to the parent's selectedCustomer property.

robwormald
  • 853
  • 7
  • 6
12

Try this -

@Component({
  selector: 'child',
  inputs: ['model'],
  template: `<h3>child</h3> 
    <div>{{model.prop1}}</div>
    <div>{{model.prop2}}<div>`
})
class Child {

}


@Component({
  selector: 'my-app',
  directives: [Child],
  template: `
  <h3>Parent</h3>
  <button (click)="updateModel()">update model</button>
  <child [model]="parentModel"></child>
  `
})
class App {
  parentModel = { prop1: '1st prop', prop2: '2nd prop' };
  constructor() {}
  updateModel() { this.parentModel.prop1 += ' more'; }
}
Kanchan
  • 1,609
  • 3
  • 22
  • 37
1

To complete the answer that Kanchan wrote here is an output. You can find all the information about outputs here in the angular Documentation: https://angular.io/api/core/Output

  selector: 'child',
  inputs: ['model'],
  template: `<h3>child</h3> 
    <div>{{model.prop1}}</div>
    <div>{{model.prop2}}<div>`
})
class Child implements OnInit {
  @Output() outPutEvent = new EventEmitter<boolean>();

  ngOnInit() {
   this.outPutEvent.emit(true);
  }
}


@Component({
  selector: 'my-app',
  directives: [Child],
  template: `
  <h3>Parent</h3>
  <button (click)="updateModel()">update model</button>
  <child [model]="parentModel"
         (outPutEvent)="outPutEffectFunction($event)"></child>
  `
})
class App {
  parentModel = { prop1: '1st prop', prop2: '2nd prop' };
  constructor() {}
  updateModel() { this.parentModel.prop1 += ' more'; }
  outPutEffectFunction(event) { return event ? 'event true' : 'event false'}
}

This answer just demonstrates the communication between 2 components, and can complement the previous answers.

Alejandro
  • 82
  • 3
  • 12