Проблема с привязкой и @ViewChild

Этот plnkr, вероятно, самый быстрый способ увидеть проблему

Я не уверен, что это просто какая-то очевидная ошибка при использовании ViewChild, но это очень странно.

Плункер показывает 3 входа:

  • Первый вход — это основной вход и кнопка, которая может сфокусировать его.
  • Второй вход связан с тем же значением, и щелчок по редактированию разблокирует ввод.
  • Третий ввод также связан с тем же значением, и нажатие кнопки «Редактировать» разблокирует ввод и переведет на него фокус.

Однако при добавлении ViewChild для получения ссылки на ввод привязка NgModel к вводу перестает работать. Но любые другие привязки, которые вы прикрепите (например, отключенные), по-прежнему будут продолжать работать. Если вы закомментируете строку 52 app/extended.component, он снова свяжется, но, очевидно, теперь он не сможет сфокусироваться.

Первый ввод/кнопка показывает, что это, по-видимому, проблема только тогда, когда вы привязываетесь к свойству из класса, который вы расширяете.


Короче говоря, когда я получаю доступ к вводу через ViewChild, моя привязка к NgModel прерывается.

То есть, учитывая базу со свойством "someValue": Binds:

@Component({
  selector: 'binding-working',
  template: `<input type="text" [(ngModel)]="someValue" />`
})
export class Working extends Base<string> {  
  constructor() { }
};

Не привязывается:

@Component({
  selector: 'binding-broken',
  template: `<input type="text" #imBroken [(ngModel)]="someValue" />`
})
export class Broken extends Base<string> {  
  @ViewChild('imBroken') input;
  constructor() { }
};

person Wrightboy    schedule 01.07.2016    source источник


Ответы (1)


Обновление 2.3.0

Отличные новости!

Согласно блогу angular http://angularjs.blogspot.ru/2016/12/angular-230-now-available.html

Теперь разработчики могут воспользоваться преимуществами наследования объектов для компонентов. Делитесь или упрощайте функциональные возможности компонентов, наследуя их от родительского компонента.

Тогда он должен работать без специального декоратора => Пример Plunker

Более подробную информацию вы можете увидеть в этой фиксации https://github.com/angular/angular/commit/f5c8e0989d85bc064f689fc3595207dfb29413f4

Старая версия

Это как задумано.

Angular2 не поддерживает полное наследование (https://github.com/angular/angular/issues/7968#issuecomment-219865739).

Ваш дочерний декоратор ViewChild переопределяет propMetadata, определенный в базовом классе Extended. Следовательно, ваш класс ExtendedInputBroken не имеет родительских свойств, таких как baseLevel и baseLevelChange.

Тьерри Темплиер написал отличную статью о наследовании классов в Angular2.

Если вы действительно хотите это сделать, я могу предложить вам следующее решение.

Просто создайте собственный декоратор следующим образом:

function InheritPropMetadata() {
  return (target: Function) => {
    const targetProps = Reflect.getMetadata('propMetadata', target);

    const parentTarget = Object.getPrototypeOf(target.prototype).constructor;
    const parentProps = Reflect.getMetadata('propMetadata', parentTarget);

    const mergedProps = Object.assign(targetProps, parentProps);

    Reflect.defineMetadata('propMetadata', mergedProps, target);
  };
};

А затем примените его к своему классу ExtendedInputBroken:

@InheritPropMetadata()
export class ExtendedInputBroken extends Extended<string> implements OnInit {
  ...

демонстрация Plunker

Эта ссылка может вас заинтересовать:

person yurzui    schedule 02.07.2016