绑定和@ViewChild 问题
Issue with binding and @ViewChild
This plnker 可能是查看问题的最快方式
我不确定这是否只是使用 ViewChild 时的一些明显问题,但这很奇怪。
plunker 显示 3 个输入:
- 第一个输入是一个基本输入和一个可以聚焦它的按钮。
- 第二个输入绑定相同的值,点击编辑将
解锁输入。
- 第三个输入也绑定到相同的值,
然后单击编辑将解锁输入并赋予其焦点。
但是,当添加 ViewChild 以获取对输入的引用时,输入上的 NgModel 绑定停止工作。但是您附加的任何其他绑定(如禁用)仍将继续运行。如果你注释掉app/extended.component的第52行,它会再次绑定,但显然现在它无法聚焦。
第一个 input/button 表明这显然只是一个问题,当您从您正在扩展的 class 绑定到 属性 时。
简而言之,当我通过 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() { }
};
更新 2.3.0
好消息!
根据 angular 博客 http://angularjs.blogspot.ru/2016/12/angular-230-now-available.html
Developers can now take advantage of object inheritance for
components. Share or simplify component functionality by inheriting
from a parent component.
那么它应该在没有自定义装饰器的情况下工作=>
Plunker Example
您可以在此提交中看到更多详细信息https://github.com/angular/angular/commit/f5c8e0989d85bc064f689fc3595207dfb29413f4
旧版本
这是设计好的。
Angular2 不支持完全继承 (https://github.com/angular/angular/issues/7968#issuecomment-219865739)。
您的 child ViewChild
装饰器覆盖了基 Extended
class 中定义的 propMetadata
。因此,您的 ExtendedInputBroken
class 没有 parent 属性,例如 baseLevel
和 baseLevelChange
Thierry Templier 写了一篇关于 Angular2 中的 class 继承的精彩文章
如果您真的想这样做,我可以为您提供以下解决方案。
只需像这样创建自定义装饰器:
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
class:
@InheritPropMetadata()
export class ExtendedInputBroken extends Extended<string> implements OnInit {
...
这个 link 可能会让您感兴趣:
This plnker 可能是查看问题的最快方式
我不确定这是否只是使用 ViewChild 时的一些明显问题,但这很奇怪。
plunker 显示 3 个输入:
- 第一个输入是一个基本输入和一个可以聚焦它的按钮。
- 第二个输入绑定相同的值,点击编辑将 解锁输入。
- 第三个输入也绑定到相同的值, 然后单击编辑将解锁输入并赋予其焦点。
但是,当添加 ViewChild 以获取对输入的引用时,输入上的 NgModel 绑定停止工作。但是您附加的任何其他绑定(如禁用)仍将继续运行。如果你注释掉app/extended.component的第52行,它会再次绑定,但显然现在它无法聚焦。
第一个 input/button 表明这显然只是一个问题,当您从您正在扩展的 class 绑定到 属性 时。
简而言之,当我通过 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() { }
};
更新 2.3.0
好消息!
根据 angular 博客 http://angularjs.blogspot.ru/2016/12/angular-230-now-available.html
Developers can now take advantage of object inheritance for components. Share or simplify component functionality by inheriting from a parent component.
那么它应该在没有自定义装饰器的情况下工作=> Plunker Example
您可以在此提交中看到更多详细信息https://github.com/angular/angular/commit/f5c8e0989d85bc064f689fc3595207dfb29413f4
旧版本
这是设计好的。
Angular2 不支持完全继承 (https://github.com/angular/angular/issues/7968#issuecomment-219865739)。
您的 child ViewChild
装饰器覆盖了基 Extended
class 中定义的 propMetadata
。因此,您的 ExtendedInputBroken
class 没有 parent 属性,例如 baseLevel
和 baseLevelChange
Thierry Templier 写了一篇关于 Angular2 中的 class 继承的精彩文章
如果您真的想这样做,我可以为您提供以下解决方案。
只需像这样创建自定义装饰器:
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
class:
@InheritPropMetadata()
export class ExtendedInputBroken extends Extended<string> implements OnInit {
...
这个 link 可能会让您感兴趣: