angularjs - ngModel Binding en el menú desplegable de Polymer(Angular2)
typescript polymer-1.0 (1)
Ejemplo de trabajo completo. No encontré una forma adecuada de aplicar ControlValueAccessor
a <paper-dropdown-menu>
sino que lo agregué a la <paper-listbox>
embebida. La única desventaja es que puede necesitar un ControlValueAccessor
diferente si utiliza un contenido diferente para <paper-dropdown-menu>
, la ventaja es que puede usar el ControlValueAccessor
con <paper-listbox>
incluso cuando no está envuelto en un <paper-dropdown-menu>
import {
Component,
Directive,
Renderer,
forwardRef,
Provider,
ElementRef,
ViewEncapsulation,
} from ''@angular/core'';
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from ''@angular/common'';
const PAPER_MENU_VALUE_ACCESSOR = new Provider(
NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => PaperMenuControlValueAccessor), multi: true});
@Directive({
selector: ''paper-listbox'',
host: {''(iron-activate)'': ''onChange($event.detail.selected)''},
providers: [PAPER_MENU_VALUE_ACCESSOR]
})
export class PaperMenuControlValueAccessor implements ControlValueAccessor {
onChange = (_:any) => {
};
onTouched = () => {
};
constructor(private _renderer:Renderer, private _elementRef:ElementRef) {
console.log(''PaperMenuControlValueAccessor'');
}
writeValue(value:any):void {
//console.log(''writeValue'', value);
this._renderer.setElementProperty(this._elementRef.nativeElement, ''selected'', value);
}
registerOnChange(fn:(_:any) => {}):void {
this.onChange = fn;
}
registerOnTouched(fn:() => {}):void {
this.onTouched = fn;
}
}
@Component({
selector: ''my-app'',
directives: [PaperMenuControlValueAccessor],
encapsulation: ViewEncapsulation.None,
template: `
<h2>Hello {{name}}</h2>
<paper-menu>
<paper-item>Item 1</paper-item>
<paper-item>Item 2</paper-item>
</paper-menu>
<paper-dropdown-menu label="Dinosaurs" >
<paper-listbox class="dropdown-content" [(ngModel)]="selected">
<paper-item *ngFor="let item of items">{{item}}</paper-item>
</paper-listbox>
</paper-dropdown-menu>
<div>selected: {{items[selected]}}</div>
`,
})
export class AppComponent {
items = [''allosaurus'', ''brontosaurus'', ''carcharodontosaurus'', ''diplodocus''];
selected = 3;
name:string;
constructor() {
this.name = ''Angular2 (Release Candidate!)''
}
ngAfterViewInit() {
//this.selected = this.diplodocus;
}
}
Actualizar
Encontré una respuesta similar para PaperDropdownMenu
lugar del PaperListbox
Bind angular 2 para la lista desplegable de polímero
Ok, hasta ahora pude enlazar <paper-radio>
, <paper-checkbox>
con ngModel utilizando un ControlValueAccessor
personalizado para cada uno de ellos. Ahora estoy atascado en <paper-dropdown-menu>
Aquí el escenario, puedo capturar el menú desplegable de papel (seleccionar hierro) pero no puedo enlazar de dos vías, es decir, usar ngModel a continuación es la clase de acceso HTML y personalizada
Mi formulario.html
<paper-dropdown-menu [(ngModel)]="mymodel.selection" label="Your Fix">
<paper-menu class="dropdown-content">
<paper-item value="1" ngDefaultControl>Coffee</paper-item>
<paper-item value="2" ngDefaultControl>Cigarettes</paper-item>
<paper-item value="3" ngDefaultControl>Chivas</paper-item></paper-menu>
</paper-dropdown-menu>
Y mi clase de accesorios personalizados
/**
* Created by pratik on 12/5/16.
*/
import {
Query,
Directive,
Renderer,
Self,
forwardRef,
Provider,
ElementRef,
QueryList
} from ''angular2/core'';
import {ObservableWrapper} from ''angular2/src/facade/async'';
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from ''angular2/common'';
import {CONST_EXPR} from ''angular2/src/facade/lang'';
const SELECT_VALUE_ACCESSOR = CONST_EXPR(new Provider(
NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => SelectControlValueAccessor), multi: true}));
/**
* Marks `<option>` as dynamic, so Angular can be notified when options change.
*
* ### Example
*
* ```
* <select ngControl="city">
* <option *ngFor="#c of cities" [value]="c"></option> Need to change to paper-item
* </select>
* ```
*/
@Directive({selector: ''option''}) // Tried changing to paper-item but still doesn''t work
export class NgSelectOption {
}
/**
* The accessor for writing a value and listening to changes on a select element.
*/
@Directive({
selector: ''paper-dropdown-menu[ngControl],paper-dropdown-menu[ngFormControl],paper-dropdown-menu[ngModel]'',
host: {
''(iron-select)'': ''onChange($event.target.value)'',
''(input)'': ''onChange($event.target.value)'',
''(blur)'': ''onTouched()''
},
bindings: [SELECT_VALUE_ACCESSOR]
})
export class SelectControlValueAccessor implements ControlValueAccessor {
value: string;
onChange = (_) => {};
onTouched = () => {};
constructor(private _renderer: Renderer, private _elementRef: ElementRef,
@Query(NgSelectOption, {descendants: true}) query: QueryList<NgSelectOption>) {
this._updateValueWhenListOfOptionsChanges(query);
}
writeValue(value: any): void {
this.value = value;
this._renderer.setElementProperty(this._elementRef, ''value'', value);
}
registerOnChange(fn: () => any): void { this.onChange = fn; }
registerOnTouched(fn: () => any): void { this.onTouched = fn; }
private _updateValueWhenListOfOptionsChanges(query: QueryList<NgSelectOption>) {
ObservableWrapper.subscribe(query.changes, (_) => this.writeValue(this.value));
}
}