iPhone sqlite проблема: “из памяти” на sqlite3_prepare_v2

Вот демонстрация Stackblitz директивы

Я внес несколько изменений в ваш код, вот что я предлагаю:

[ 1143]

  • Измените тип appInputMaxLength на номер
  • Используйте API Renderer2 настолько, насколько это возможно, для кросс-платформенной совместимости.
  • Используйте частное свойство div для хранения вашего div и обновите его позже, создайте его с помощью this.renderer.createElement('div')
  • Используйте this.renderer.insertBefore(this.el.nativeElement.parentNode, this.div, this.el.nativeElement.nextSibling), чтобы вставить его после хоста
  • Прослушать изменения используя событие input, получите значение из события, затем получите его длину и обновите div
  • Вам не нужно хранить переменную currentValue, просто получите длину из входное значение или событие
  • Используйте this.renderer.setProperty(this.div, 'innerText', ...); для обновления текста вашего элемента div
  • Удалите элемент div, так как Angular не будет его отслеживать. Для этого вы не можете использовать this.renderer.removeChild(this.el.nativeElement.parent, this.div), так как ngOnDestroy вызывается после удаления DOM, и ссылка parent будет нулевой. Вы должны напрямую позвонить this.div.remove() ( см. Этот выпуск Github ).

    • Обновлен код директивы

    import { AfterViewInit, Directive, ElementRef, HostListener, Input, OnInit, Renderer2, OnDestroy } from '@angular/core';
    
    @Directive({
      selector: '[appInputMaxLength]'
    })
    export class InputMaxLengthDirective implements OnInit, AfterViewInit, OnDestroy {
      @Input() appInputMaxLength: number;
      private div: HTMLDivElement;
    
      constructor(private el: ElementRef, private renderer: Renderer2) {}
    
      @HostListener('input', ['$event']) onChange(event) {
        this.update(event.target.value.length);
      }
    
      ngOnInit() {
        this.renderer.setAttribute(this.el.nativeElement, 'maxLength', this.appInputMaxLength.toString());
      }
    
      ngOnDestroy() {
        if (this.div) {
          this.div.remove();
        }
      }
    
      ngAfterViewInit() {
        this.div = this.renderer.createElement('div');
        this.renderer.insertBefore(this.el.nativeElement.parentNode, this.div, this.el.nativeElement.nextSibling);
        this.update(this.el.nativeElement.value.length);
      }
    
      private update(length: number) {
        this.renderer.setProperty(this.div, 'innerText', `${length} / ${this.appInputMaxLength}`);
      }
    }
    

    Используйте его следующим образом со значением ввода числа:

    
    



    Код директивы, совместимый с ngModel

    Если вы хотите, чтобы ваша директива работала, когда ngModel привязан к входу, и обновляйте соответственно, если модель изменяется Вы можете получить инъекцию хоста ngModel и затем подписаться на его valueChange наблюдаемый:

    import { AfterViewInit, Directive, ElementRef, HostListener, Input, OnInit, Renderer2, Optional, OnDestroy } from '@angular/core';
    import { NgModel } from '@angular/forms';
    import { Subject } from 'rxjs';
    import { takeUntil } from 'rxjs/operators';
    
    @Directive({
      selector: '[appInputMaxLength]'
    })
    export class InputMaxLengthDirective implements OnInit, AfterViewInit, OnDestroy {
      @Input() appInputMaxLength: number;
      private div: HTMLDivElement;
      private destroyed$ = new Subject();
    
      constructor(private el: ElementRef, private renderer: Renderer2, @Optional() private ngModel: NgModel) {}
    
      @HostListener('input', ['$event']) onChange(event) {
        if (!this.ngModel) {
          this.update(event.target.value.length);
        }
      }
    
      ngOnInit() {
        this.renderer.setAttribute(this.el.nativeElement, 'maxLength', this.appInputMaxLength.toString());
        if (this.ngModel) {
          this.ngModel.valueChanges.pipe(takeUntil(this.destroyed$)).subscribe(value => {
            this.update(value.length);
          })
        }
      }
    
      ngAfterViewInit() {
        this.div = this.renderer.createElement('div');
        this.renderer.insertBefore(this.el.nativeElement.parentNode, this.div, this.el.nativeElement.nextSibling);
        this.update(this.el.nativeElement.value.length);
      }
    
      ngOnDestroy() {
        this.destroyed$.next();
        this.destroyed$.complete();
        if (this.div) {
          this.div.remove();
        }
      }
    
      private update(length: number) {
        this.renderer.setProperty(this.div, 'innerText', `${length} / ${this.appInputMaxLength}`);
      }
    }
    

    Затем вы можете использовать вашу директиву на входе с ngModel:

    [113 ]

    10
    задан Chris Dolan 21 June 2011 в 05:11
    поделиться