首页 文章

将角2模型与聚合物下拉结合

提问于
浏览
5

我本周末决定花点时间看看Angular 2和Polymer . 我真的对棱角2感兴趣,并且真的想开始用它来构建一些东西 . 现在从Angular 2开始的一个缺点是还没有好的组件库 . 但是,由于Angular 2声称它应该与Web Components一起工作得很好,我想给Polymer一个尝试 . 我成功地将数据绑定到像输入字段这样的简单组件 . 我现在坚持的是如何将模型绑定到纸张下拉菜单的选定对象 . 因为我对这两者都很新,所以我真的不知道怎么做,但这是我到目前为止所尝试过的 . 有没有人完成将角度2模型绑定到聚合物下拉?

<paper-dropdown-menu  >
   <paper-menu class="dropdown-content" valueattr="id" [(ng-model)]="model">
       <paper-item *ng-for="#m of options" id="{{m.id}}" (click)="onClick()">{{m.name}}</paper-item>
   </paper-menu>
</paper-dropdown-menu>

编辑:我现在已经创建了一个似乎可以接受的ValueAccessor,但有一个例外 . 我尝试通过在writeValue方法中设置selected属性来使下拉列表具有预先选择的值 . 起初这似乎有效,但在我做了这个改变后,我再也无法改变选定的值了 . 如果我对模板中的值进行硬编码,那么它似乎与角度和聚合物有关 . 我试着跟踪堆栈跟踪并比较两者之间的差异 . 当我对值进行硬编码时,执行select的setter方法,触发item-select事件 . 当我在valueAccessor中设置属性时,我遵循相同的跟踪,不再执行setter方法 . 似乎是角2和聚合物之间相互作用的问题 .

import {Directive, ControlValueAccessor, ElementRef, Renderer, NG_VALUE_ACCESSOR, Provider, forwardRef} from "angular2/angular2"
import {isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
import {setProperty} from "angular2/src/common/forms/directives/shared"

const PAPER_DROPDOWN_VALUE_ACCESSOR = CONST_EXPR(new Provider(
    NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => PaperDrowpdownMenuAccessor), multi: true}));

@Directive({
  selector: 'paper-menu[ng-model]',
  bindings: [PAPER_DROPDOWN_VALUE_ACCESSOR]
})
export class PaperDrowpdownMenuAccessor implements ControlValueAccessor {

  onChange = (_) => {};
  onTouched = () => {};

  constructor(private _renderer: Renderer, private _elementRef: ElementRef) {
    var self = this;
    this._elementRef.nativeElement.addEventListener('iron-select', function(e, v, s){
      console.log(e.target.selected);
      self.onChange(e.target.selected);
    });
  }

  writeValue(value: any): void {
    if(value){
      if(this._elementRef.nativeElement.select) {
        this._elementRef.nativeElement.select(value);
      }
      else {
        //this._elementRef.nativeElement.attributes["selected"]
        setProperty(this._renderer, this._elementRef, 'selected', value);
      }
    }       
  }

  registerOnChange(fn: () => any): void { 
    this.onChange = fn; 
  }
  registerOnTouched(fn: () => any): void { this.onTouched = fn; }
}

1 回答

  • 3

    我终于通过实现一个自定义的Value Accessor来解决这个问题,主要是通过查看默认值访问器是如何实现的 . https://github.com/angular/angular/blob/2.0.0-alpha.46/modules/angular2/src/common/forms/directives/default_value_accessor.ts

    由于纸质菜单希望将预先选择的值设置为渲染的html中的属性,因此我对此有点挣扎 . 在我的第一次尝试中,我使用angulars内部setProperty来设置所选值 . 但是,这会设置DOM属性而不是HTML属性,导致聚合物没有创建所选的get,set属性,这会阻止菜单触发下拉菜单侦听的铁选事件 . 经验教训,记住HTML和DOM之间的区别 .

    import {Directive, ControlValueAccessor, ElementRef, Renderer, NG_VALUE_ACCESSOR, Provider, forwardRef} from "angular2/angular2"
    import {CONST_EXPR} from 'angular2/src/facade/lang';
    
    const PAPER_MENU_VALUE_ACCESSOR = CONST_EXPR(new Provider(
        NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => PaperMenuAccessor), multi: true}));
    
    @Directive({
      selector: 'paper-menu[ng-model]',
      bindings: [PAPER_MENU_VALUE_ACCESSOR]
    })
    export class PaperMenuAccessor implements ControlValueAccessor {
    
      onChange = (_) => {};
      onTouched = () => {};
    
      constructor(private _renderer: Renderer, private _elementRef: ElementRef) {
        this._elementRef.nativeElement.addEventListener('iron-select', (e) => {
          this.onChange(e.target.selected);
        });
      }
    
      writeValue(value: any): void {
        if(this._elementRef.nativeElement.select) {
          this._elementRef.nativeElement.select(value);
        }
        else {
          this._elementRef.nativeElement.setAttribute("selected", value);
        }   
      }
    
      registerOnChange(fn: () => any): void { this.onChange = fn; }
      registerOnTouched(fn: () => any): void { this.onTouched = fn; }
    }
    

相关问题