-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Angular常见错误及解决方案 #24
Comments
Cannot assign to a reference or variable!这是一个什么错误,翻译成为无法分配给引用或变量(小细节:有些错误,你不知道什么意思时候,你可以把英文翻译成中文,你英文很差情况下,谷歌翻译很不错) 引用或变量,我不知道是什么鬼,但是我知道angular有个东西叫模板引用变量。 优点:这个模板完全是完全自包含的。它没有绑定到组件,组件也没做任何事情。这里的自包含的意思是:它不用与Component进行交互。
举个栗子: <my-select #select></select> 比如我写了一个 <my-select #select></select>
// 新需求
<button (click)="select.open()">打开</button> 就是这么容易。如果你还不知道赶紧用它把,它还可以ts获取: // 获取一个
@ViewChild('select', { read: SelectComponent }) select: SelectComponent;
// 获取一组
@ViewChildren('selects', { read: SelectComponent }) select: QueryList<SelectComponent>;
回到错误,这才是关键。 我们看到模板引用变量调用是 那么很好理解的错误,无法分配给引用或变量,这里引用是指模板引用变量,变量指我们在ts里面定义class的属性。 解决方案很简单,别让他们重名就好了。
指令需要写导出 @Directive({
selector: '[appRefresh]',
exportAs: 'refresh'
})
export class RefreshDirective implements OnDestroy {
load() {}
} <div appRefresh #refreshRef="refresh">...code</div>
<button (click)="refreshRef.load()">加载</button>
|
Unexpected value 'undefined' imported by the module 'XxxxxModule'翻译中文:模块“XxxxxModule”导入的意外值“undefined”。 我们先看下angular模块怎么定义的: NgModule({
imports: [
SharedModule,
RouterModule.forChild(routes)
],
declarations: [XxxxComponent]
})
export class XxxxxModule { } 这是一个基本的业务模块,没有 现在错误是提示根据字面意思是来自 如果你找不到问题的时候,可以通过排除法。因为我们已经锁定范围了,剩下就一个一个找问题。 我们先把 因为这个模块看命名知道是共享模块,大概就是导出当前模块需要的一些其他模块,组件什么的。 可以先将 我先说下我这个报错原因: 我开始是这么写的 import { SharedModule } from '../shared'; 因为在 按我正常理解是不需要在这样写: 我改成新的写法: import { SharedModule } from '../shared/shared.module'; 改成这样就不报错了,哈哈,那么就说明我这个 export * from './shared.module'; 我写的这样的,并没有错,不知道原因它不找不到(可能cli抽风)。 这个问题原因就是导入模块时候,没有拿到导出模块,那个导入模块就变成了 |
关于循环依赖问题什么叫循环依赖,比如我们创建一个
那么我们组件写法就是 <my-select>
<my-option>项</my-option>
</my-select>
<my-select>
<my-optgroup label="分组">
<my-option>项</my-option>
</my-optgroup>
</my-select> 如果我在 在angular写法就比较简单,只需要这样既可: export class OptionComponent {
constructor(
@Optional() readonly group: OptgroupComponent
) {}
}
这样没啥问题,没什么问题。 我现在有个需求想知道 先看下我们的 <label class="optgroup-label">{{ label }}</label>
<ng-content select="my-option, ng-container"></ng-content> 按我们正常理解使用: /** 所有定义的选择选项。 */
@ContentChildren(OptionComponent, { descendants: true }) options: QueryList<OptionComponent>; 这样就可以获取到 ngAfterContentInit() {
this.options.changes.subscribe((option) => console.log('ngAfterContentInit', option));
} 这样就好获取到 翻译错误:无法为“SimOptgroupComponent”的属性“options”构造查询,因为没有定义查询选择器。 简单理解就是找不到 改成下面写法就行啦,需要加上tslint报错问题。 /** 所有定义的选择选项。 */
// tslint:disable-next-line:no-use-before-declare
@ContentChildren(forwardRef(() => OptionComponent), { descendants: true }) options: QueryList<OptionComponent>; 如果你的 |
打包时候出现错误
这是一个什么错误,看着一脸懵逼,翻译错误 虽然翻译有点直白,大概意思就是,这个组件没有在模块里面申明,又存在这个组件,打包时候就找不到组件和模块依赖关系。 引起这个原因有2个:
那么解决问题方案就是:如果需要使用去模块申明它,如果无用的废弃组件及时删除它。 |
关于
|
Angular开发中,有时候有些错误让人一脸懵逼,不知道该如何下手,接下来我就介绍一下我在我使用angular中遇到的问题和解决方案(欢迎你留下你的问题和解决方案,让我们angular开发更轻松容易):
关于依赖注入问题
经常看有人在群里问下面这张图是什么问题,
上面问题解答是
AppComponent
依赖NameService
服务,NameService
却没有申明。解决方案去申明注册:(注意:服务注册位置决定服务作用域)
全局申明:(一般用于全局数据共享使用,如果是注册到全局,推荐第一种方式,因为它对打包会有优化)
模块申明:(一般用于该模块下数据共享使用,你也可以导出给其他模块使用)
组件申明1:(一般用于该组件下数据共享使用,它会携带一个
OnDestroy
生命周期)组件申明2:(一般用于该组件下数据共享使用,它会携带一个
OnDestroy
生命周期)什么是
contentChildren
,就是<ng-content></ng-content>
的内容。为什么依赖注入需要写
private
基本很多栗子都是这样的来写依赖注入:
有人就奇怪为什么我一定要写一个
private
,可以不写么,可以,但是会报错,如果不写ts只是当他是类参数,其实
constructor(private nameService: NameService) { }
是一个语法糖。如果不写
private
:编辑器会提示:类型“AppComponent”上不存在属性“nameService”
试想一下ES6的class怎么写的:
constructor里的参数,ts看来它是构造参数,不是一个类的属性,如果要实现属性功能,你需要这样来写:
最后总结:你在ts写方法和属性时候公开可以不用写
public
关键字,但是在constructor
里写依赖注入时如果需要写成公开时候一定要写public
关键词。为什么创建angular组件模块都需要带上
CommonModule
。angular使用中一定要注意,组件,指令,管道,服务都是封装的在模块里,如果想要给其他模块里面组件使用,一定要导出。如果当前模块想要使用别人模块一定要导入。
CommonModule
里面携带angular自带组件,指令,管道等,如果你带上它不能使用*ngIf
,*ngFor
等。最后总结,记住两点,你可以轻松玩转angular模块:
exports
imports
'app-xxx' is not a known element
这是一个什么沙雕错误,翻译成中文
app-xxx
不是一个已知的元素,再说简单点就不是一个标准的HTML标签,算一个自定义标签,angular不认识它。问题找到根源了,出现这个错误有个原因:
这里是
vs code
提示错误,翻译里面3句话比较重要:一个组件只能在一个
NgModule
申明,不能重复申明,如果A和B模块都申明一个c组件,那么就会报错,提醒你写一个D模块去申明c组件,A和B模块去引用D模块。这就是传说的共享模块思路来源。这是内置的angular指令,如果你当前模块没有导入
CommonModule
,就会报错Can't bind to 'ngIf' since it isn't a known property of 'div'.
解决方案只需要导入
CommonModule
,使用其他模块组件,指令,管道也是一样的道理。Angular Language Service
提示:Can't bind to 'appCode' since it isn't a known property of 'div'
这又是一个什么沙雕错误,翻译成中文
appCode
不是一个div上面一个属性,再说简单点就不是一个标准的HTML标签标准属性,算一个自定义属性,angular不认识它。需要先去了解一下HTML attribute 与 DOM property 的对比
这里只能推测你有2个意图:
那你需要这样去操作:使用
attr.xxxx
@Input
属性。这种情况也分2种,一直是你没有申明,或者导入。
这个参照'app-xxx' is not a known element解决。
意思是你没有在组件或指令使用
@Input()
装饰器申明它,或者你属性名写错了。解决方案请正确书写和申明。
The text was updated successfully, but these errors were encountered: