ngModel Binding on Polymer dropdown (Angular2)

好久不见. 提交于 2019-11-29 16:48:03
Günter Zöchbauer

Full working example. I didn't find a proper way to apply the ControlValueAccessor to <paper-dropdown-menu> but instead added it to the embeeded <paper-listbox>. The only disadvantage is that you might need a different ControlValueAccessor if you use a different content for <paper-dropdown-menu>, the advantage is that you can use the ControlValueAccessor with <paper-listbox> even when it's not wrapped in a <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;
  }
}

Plunker example

Update

I found a similar answer for PaperDropdownMenu instead of PaperListbox Bind angular 2 model to polymer dropdown

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!