ngModel Binding on Polymer dropdown (Angular2)

前端 未结 1 710
死守一世寂寞
死守一世寂寞 2020-12-22 00:05

Ok so far I was successfully able to bind , with ngModel by using a Custom ControlValueAccessor

相关标签:
1条回答
  • 2020-12-22 00:49

    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

    0 讨论(0)
提交回复
热议问题