Angular2 EXCEPTION:无法读取null的属性'off'

时间:2017-01-20 17:08:09

标签: angular laravel-5 angular2-forms angular2-http

我不知道是什么原因引起的。看起来它可能是第三方插件。

我的x-editable组件

declare var $: any;

@Component({
  selector: 'x-editable',
  template: '<a attr.id="{{widgetId}}" class="{{className}}"><ng-content></ng-content>{{model }}</a>'
})
export class XEditableComponent implements OnInit, AfterContentChecked {

  @Input() model: any = '';
  @Output() modelChange = new EventEmitter();
  @Input() Name: string = '';
  @Input() type: any = 'text';
  @Input() value: any;
  @Input() pk: any;

  @Output() change = new EventEmitter();

  public widgetId: any;
  public widgetsCounter = 0;

  private _options: any;

  constructor(private el: ElementRef) {
    this.widgetId = 'x-editable' + this.widgetsCounter++;
  }

  ngOnInit() {
    this.render();
  }

  ngAfterContentChecked() {
    if (this._options && ['type',
      'placement',
      'mode',
      'value',
      'disabled',
      'placeholder',
      'originalTitle',
      'source',
      'showbuttons',

      'template',
      'viewformat',
      'format',
      'pk',
    ].some((it) => {
      return this._options[it] !== this[it];
    })) {
      this.render();
    }

  }

  render() {
    let element = $(this.el.nativeElement);
    let options = {
      type: this.type,
      placement: this.placement,
      mode: this.mode,
      value: this.value,
      disabled: this.disabled,
      placeholder: this.placeholder,
      originalTitle: this.originalTitle,
      source: this.source,
      showbuttons: this.showbuttons,
      template: this.template,
      viewformat: this.viewformat,
      format: this.format,
      pk: this.pk,
    };

    element.editable('destroy');
    element.editable(options);

    element.on('save', (e, params) => {
      this.model = params.newValue;
      this.modelChange.emit(params.newValue);

      let data = {};
      data['id'] = this.pk;
      data[this.Name] = params.newValue;

      this.change.emit(data);
    });

    this._options = options;
  }
}

发出

export class MenuTableSelectedFormComponent implements OnInit {

    @Input() public selectedMenu: Menu;
    @Output() public selectedMenuChange = new EventEmitter();

    @Output() updatePage = new EventEmitter();

    constructor() { }

    ngOnInit() { }

    updateMenuPage($event) {
        // update the parent
        this.updatePage.emit($event);
    }

}

发送给保存数据的父级(发出请求)

export class MenuTableListComponent {

    @Input() public menus: any;
    @Input() public selectedMenu: Menu;
    @Output() public selectedMenuChange = new EventEmitter();
    @Output() public showForm = new EventEmitter();


    /**
     * @param $event - data from the child component for updating the model
     */
    updateMenuPage($event) {
        let id = $event.id;
        delete $event['id'];

        // save the data here
        this.page.update(id, $event)
            .subscribe(res => {
                this.notify.success('Menu Saved', 'Menu saved successfully!');
            });
    }    
}

我正在使用angular2-jwt来处理我的http请求。其余的是我自己的服务,通过angular2-jwt运行http请求。

特别是当我在x-editable组件中发出数据(this.change.emit($ event))时会发生此错误。然后再次,我已经完全删除了x-editable组件,并且只是定期用[(ngModel)]绑定一个输入字段,我得到了同样的错误,这让我相信绑定不是问题。

TypeError: Cannot read property 'off' of null
    at eval (eval at module.exports (addScript.js:9), <anonymous>:6:28424)
    at HTMLDivElement.d (eval at module.exports (addScript.js:9), <anonymous>:6:25567)
    at HTMLDivElement.e (eval at module.exports (addScript.js:9), <anonymous>:3:5222)
    at HTMLDivElement.handle (eval at module.exports (addScript.js:9), <anonymous>:6:1043)
    at HTMLDivElement.dispatch (eval at module.exports (addScript.js:9), <anonymous>:3:7537)
    at HTMLDivElement.r.handle (eval at module.exports (addScript.js:9), <anonymous>:3:5620)
    at Object.trigger (eval at module.exports (addScript.js:9), <anonymous>:4:4818)
    at HTMLDivElement.eval (eval at module.exports (addScript.js:9), <anonymous>:4:5328)
    at Function.each (eval at module.exports (addScript.js:9), <anonymous>:2:2861)
    at n.fn.init.each (eval at module.exports (addScript.js:9), <anonymous>:2:845)
    at n.fn.init.trigger (eval at module.exports (addScript.js:9), <anonymous>:4:5304)
    at e (eval at module.exports (addScript.js:9), <anonymous>:6:743)
    at ZoneDelegate.invokeTask (zone.js:275)
    at Object.onInvokeTask (ng_zone.js:262)
    at ZoneDelegate.invokeTask (zone.js:274)

事情是这个错误在我看来与错误的导入有关吗?

2 个答案:

答案 0 :(得分:0)

我认为您的模板应该是[attr.id]而不是attr.id。像:

template: '<a [attr.id]="{{widgetId}}" class="{{className}}"><ng-content></ng-content>{{model }}</a>'

答案 1 :(得分:0)

我不确定这是否是原因,但我设法通过删除AfterContentChecked实现来修复它。

所以

之前:

declare var $: any;

@Component({
  selector: 'x-editable',
  template: '<a attr.id="{{widgetId}}" class="{{className}}"><ng-content></ng-content>{{model }}</a>'
})
export class XEditableComponent implements OnInit, AfterContentChecked {
  @Input() model: any = '';
  @Output() modelChange = new EventEmitter();
  @Input() Name: string = '';
  @Input() type: any = 'text';
  @Input() value: any;
  @Input() pk: any;
  @Output() change = new EventEmitter();
  public widgetId: any;
  public widgetsCounter = 0;
  private _options: any;
  constructor(private el: ElementRef) {
    this.widgetId = 'x-editable' + this.widgetsCounter++;
  }
  ngOnInit() {
    this.render();
  }
  ngAfterContentChecked() {
    if (this._options && ['type',
      'placement',
      'mode',
      'value',
      'disabled',
      'placeholder',
      'originalTitle',
      'source',
      'showbuttons',
      'template',
      'viewformat',
      'format',
      'pk',
    ].some((it) => {
      return this._options[it] !== this[it];
    })) {
      this.render();
    }
  }
  render() {
    let element = $(this.el.nativeElement);
    let options = {
      type: this.type,
      placement: this.placement,
      mode: this.mode,
      value: this.value,
      disabled: this.disabled,
      placeholder: this.placeholder,
      originalTitle: this.originalTitle,
      source: this.source,
      showbuttons: this.showbuttons,
      template: this.template,
      viewformat: this.viewformat,
      format: this.format,
      pk: this.pk,
    };
    element.editable('destroy');
    element.editable(options);
    element.on('save', (e, params) => {
      this.model = params.newValue;
      this.modelChange.emit(params.newValue);

之后:

declare var $: any;

@Component({
  selector: 'x-editable',
  template: '<a attr.id="{{widgetId}}" class="{{className}}"><ng-content></ng-content>{{model }}</a>'
})
export class XEditableComponent implements OnInit {

  @Input() model: any = '';
  @Output() modelChange = new EventEmitter();

  @Input() Name: string = '';

  @Input() type: any = 'text';
  @Input() placement: any;
  @Input() value: any;
  @Input() mode: any;
  @Input() disabled: any = false;
  @Input() placeholder: any;
  @Input() originalTitle: any;
  @Input() source: any;
  @Input() showbuttons: any;
  @Input() template: any;
  @Input() viewformat: any;
  @Input() format: any;
  @Input() className: any;
  @Input() pk: any;

  @Output() change = new EventEmitter();

  public widgetId: any;
  public widgetsCounter = 0;

  private _options: any;

  constructor(private el: ElementRef) {
    this.widgetId = 'x-editable' + this.widgetsCounter++;
  }

  ngOnInit() {
    this.render();
  }

  render() {
    let element = $(this.el.nativeElement);
    let options = {
      type: this.type,
      placement: this.placement,
      mode: this.mode,
      value: this.value,
      disabled: this.disabled,
      placeholder: this.placeholder,
      originalTitle: this.originalTitle,
      source: this.source,
      showbuttons: this.showbuttons,
      template: this.template,
      viewformat: this.viewformat,
      format: this.format,
      pk: this.pk,
    };

    element.editable('destroy');
    element.editable(options);

    element.on('save', (e, params) => {
      this.model = params.newValue;
      this.modelChange.emit(params.newValue);

      let data = {};
      data['id'] = this.pk;
      data[this.Name] = params.newValue;

      this.change.emit(data);
    });

    this._options = options;
  }
}

我不再收到错误......