2016-07-01 4 views
1

This plnker, вероятно, самый быстрый способ, чтобы увидеть проблемуПроблема с привязкой и @ViewChild

я не уверен, если это просто какой-то явный глюк при использовании ViewChild, но это очень странно.

plunker показывает 3 входа:

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

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

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


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

То есть, учитывая базу со свойством "SomeValue": Становится персональным:

@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() { } 
}; 

ответ

6

Обновление 2.3.0

Отличная новость !

По угловому блоге Теперь http://angularjs.blogspot.ru/2016/12/angular-230-now-available.html

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

Итак, он должен работать без пользовательского декоратора => Plunker Example

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

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

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

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

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

Тьерри TEMPLIER написал большую статью о наследовании классов в 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 demo

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

Смежные вопросы