sintaxis que modulos entre directivas diferencia comunicacion componentes componente javascript angular data-binding 2-way-object-databinding

javascript - modulos - que es un componente angular



Angular2: enlace de datos bidireccional en una variable de componente/propiedad de clase de componente? (2)

En Angular2 (Beta 6) tengo un componente para un menú principal.

<mainmenu></mainmenu>

Quiero unir un booleano para ancho o estrecho. Así que lo hice en esto:

<mainmenu [(menuvisible)]="true"></mainmenu>

Pero lo que quiero (creo) es enlazar a una propiedad de clase javascript (ya que puedo tener otras cosas que vincular pero quiero estar ordenadas usando una sola clase en el componente).

Me sale un error

EXCEPCIÓN: Errores de análisis de plantilla: Nombre de propiedad no válido ''menumodel.visible'' ("

] [(menumodel.visible)] = "menumodel.visible">

Si intento lo mismo con una sola variable en lugar de una clase, obtengo:

Errores de análisis de plantilla: Error del analizador: token inesperado ''=''

Sin embargo, este (¿enlace de una manera?) Parece funcionar (pero es posible que desee activar el menú para que se amplíe / reduzca desde otro componente, por lo que sentí que esto debería ser una propiedad de enlace de datos de dos vías):

<menu [vis]="true"></menu>

Esto es un poco de mi componente de menú:

@Component({ selector: ''menu'', templateUrl: ''./app/menu.html'', providers: [HTTP_PROVIDERS, ApplicationService], directives: [ROUTER_DIRECTIVES, FORM_DIRECTIVES, NgClass, NgForm] }) export class MenuComponent implements OnInit { mainmenu: MainMenuVM; constructor(private _applicationService: ApplicationService) { this.mainmenu = new MainMenuVM(); } // ...ngOnInit, various functions }

Aquí está mi clase MainMenu View Model

export class MainMenuVM { public visible: boolean; constructor( ) { this.visible = true; } }

Estoy tratando de crear un menú que tenga íconos y texto, pero se puede restringir solo para mostrar íconos. Emitiré este evento hacia arriba a un componente principal para alterar la posición del contenedor al lado del menú. Activar un contenedor de contenido para maximizarlo hará que el menú sea más estrecho. No estoy diciendo que esta sea la mejor manera, pero me gustaría resolver esta pregunta en particular antes de profundizar.

Tenga en cuenta: no estoy enlazando datos a un control de entrada aquí, solo estoy enlazando datos a un componente para poder modificar la IU.

Esto es de la chuleta angular

<my-cmp [(title)]="name"> Sets up two-way data binding. Equivalent to: <my-cmp [title]="name" (titleChange)="name=$event">

¡Gracias por adelantado!

ACTUALIZAR

Integrando el código de la respuesta aceptada y adaptándome para mi caso de uso particular, aquí está el código de trabajo final:

app.html

...header html content // This is what I started with <!--<menu [menuvisible]="true" (menuvisibleChange)="menuvisible=$event"></menu>--> // This is two way data binding // 1. Banana-in-a-box is the input parameter // 2. Banana-in-a-box is also the output parameter name (Angular appends it''s usage with Change in code - to follow shortly) // 3. Banana-in-a-box is the short hand way to declare the commented out code // 4. First parameter (BIAB) refers to the child component, the second refers the variable it will store the result into. // 5. If you just need an input use the remmed out code with just the first attribute / value <menu [(menuvisible)]="menuvisible"></menu> .. div content start <router-outlet></router-outlet> .. div content end

app.component.ts (root)

export class AppComponent implements OnInit{ menuvisible: Boolean; }

menu.component.ts (hijo de root)

export class MenuComponent implements OnInit { // Parameters - notice the appending of "Change" @Input() menuvisible: boolean; @Output() menuvisibleChange: EventEmitter<boolean> = new EventEmitter<boolean>(); // Init ngOnInit() { // Populate menu - fetch application list this.getApplications(); // Initially we want to show/hide the menu depending on the input parameter (this.menuvisible === true) ? this.showMenu() : this.hideMenu(); } //...more code }

menu.html

<div id="menu" [ngClass]="menuStateClass" style="position: absolute; top:0px; left: 0px;z-index: 800; height: 100%; color: #fff; background-color: #282d32"> <div style="margin-top: 35px; padding: 5px 0px 5px 0px;"> <ul class="menuList" style="overflow-x: hidden;"> <li>IsMenuVisible:{{menuvisible}}</li> <li style="border-bottom: 1px solid #3d4247"><a (click)="toggleMenu()"><i class="fa fa-bars menuIcon" style="color: white; font-size: 16px;"></i></a></li> <li *ngFor="#app of applications"> <a [routerLink]="[app.routerLink]"> <i class="menuIcon" [ngClass]="app.icon" [style.color]="app.iconColour" style="color: white;"></i> <span [hidden]="menuStateTextHidden">{{ app.name }}</span> </a> </li> </ul> </div> </div>

Recuerda importar lo que necesites, por ejemplo.

importar {Componente, EventEmitter, OnInit, Input, Output} desde ''angular2 / core'';

Recomiendo altamente este video en You Tube: Angular 2 Tutorial (2016) - Entradas y salidas


He creado un plunkr corto.

ngModel Like Two-Way-Databinding para componentes

Tiene al menos dos posibilidades para crear un enlace de datos bidireccional para componentes

V1: Con ngModel Like Syntax, debe crear una propiedad @Output con la misma línea de nombre que la propiedad @Input + "Cambiar" al final de la propiedad @Output

@Input() name : string; @Output() nameChange = new EventEmitter<string>();

con V1 ahora puede enlazar al componente secundario con la sintaxis ngModel

[(name)]="firstname"

V2. Simplemente cree una propiedad @Input y @Output con el nombre que prefiera

@Input() age : string; @Output() ageChanged = new EventEmitter<string>();

con V2 tienes que crear dos atributos para obtener el enlace de datos de dos vías

[age]="alter" (ageChanged)="alter = $event"

Componente principal

import { Component } from ''@angular/core''; @Component({ selector: ''my-app'', template: `<p>V1 Parentvalue Name: "{{firstname}}"<br/><input [(ngModel)]="firstname" > <br/><br/> V2 Parentvalue Age: "{{alter}}" <br/><input [(ngModel)]="alter"> <br/><br/> <my-child [(name)]="firstname" [age]="alter" (ageChanged)="alter = $event"></my-child></p>` }) export class AppComponent { firstname = ''Angular''; alter = "18"; }

Componente infantil

import { Component, Input, Output, EventEmitter } from ''@angular/core''; @Component({ selector: ''my-child'', template: `<p>V1 Childvalue Name: "{{name}}"<br/><input [(ngModel)]="name" (keyup)="onNameChanged()"> <br/><br/> <p>V2 Childvalue Age: "{{age}}"<br/><input [(ngModel)]="age" (keyup)="onAgeChanged()"> <br/></p>` }) export class ChildComponent { @Input() name : string; @Output() nameChange = new EventEmitter<string>(); @Input() age : string; @Output() ageChanged = new EventEmitter<string>(); public onNameChanged() { this.nameChange.emit(this.name); } public onAgeChanged() { this.ageChanged.emit(this.age); } }


Para el enlace de dos vías necesitas algo como:

@Component({ selector: ''menu'', template: ` <button (click)="menuvisible = !menuvisible; menuvisibleChange.emit(menuvisible)">toggle</button> <!-- or <button (click)="toggleVisible()">toggle</button> --> `, // HTTP_PROVIDERS should now be imports: [HttpModule] in @NgModule() providers: [/*HTTP_PROVIDERS*/, ApplicationService], // This should now be added to declarations and imports in @NgModule() // imports: [RouterModule, CommonModule, FormsModule] directives: [/*ROUTER_DIRECTIVES, FORM_DIRECTIVES, NgClass, NgForm*/] }) export class MenuComponent implements OnInit { @Input() menuvisible:boolean; @Output() menuvisibleChange:EventEmitter<boolean> = new EventEmitter<boolean>(); // toggleVisible() { // this.menuvisible = !this.menuvisible; // this.menuvisibleChange.emit(this.menuvisible); // } }

Y usalo como

@Component({ selector: ''some-component'', template: ` <menu [(menuvisible)]="menuVisibleInParent"></menu> <div>visible: {{menuVisibleInParent}}</div> ` directives: [MenuComponent] }) class SomeComponent { menuVisibleInParent: boolean; }