我正在尝试教自己如何使用Angular进行编码,但我遇到了问题。我正在为自己创建一个应用程序,并且刚刚实现了“角度材质对话框”。我把它放在包装服务中,一切似乎都很好。因此,在一个组件中,我调用包装器服务来引发类似以下内容的模式:
public assignInstrument(instrument: any): void {
this.modalDialogWrapperService.openAssignmentWindow({
product: 'instrument',
type: instrument.type,
serial: instrument.serial,
id: instrument.id
});
}
Run Code Online (Sandbox Code Playgroud)
服务方法如下所示,请注意,我在模态窗口中传递了我希望引发的组件的名称
openAssignmentWindow(instrument) {
const dialogRef = this.dialog.open(ChangeAssignmentComponent, {
data: instrument,
width: '693px',
height: '498px'
});
dialogRef.afterClosed().subscribe(() => {});
});
}
Run Code Online (Sandbox Code Playgroud)
一切正常!但是作为一名优秀的开发人员,我应该编写单元测试...因此,要测试我的组件,我需要进行以下测试(我已经包括了如何模拟服务以及其他一些代码来给测试文件留下深刻的印象)
let modalDialogWrapperServiceSpy: jasmine.SpyObj<ModalDialogWrapperService>;
const mockModalDialogWrapperService = jasmine.createSpyObj('ModalDialogWrapperService', ['openAssignmentWindow']);
mockModalDialogWrapperService.openAssignmentWindow.and.returnValue({});
TestBed.configureTestingModule({
imports: [...],
declarations: [...],
providers: [{
provide: ModalDialogWrapperService,
useValue: mockModalDialogWrapperService
}]
}).compileComponents();
beforeEach(() => {
fixture = TestBed.createComponent(InstrumentsPageComponent);
modalDialogWrapperServiceSpy = TestBed.get(ModalDialogWrapperService);
component = fixture.componentInstance;
fixture.detectChanges();
})
describe('assignInstrument', () => {
it('should call …Run Code Online (Sandbox Code Playgroud) 我今天有点失落。我想将 Stylelint 添加到我的 Angular 项目中,所以我运行了
npm install stylelint stylelint-config-standard --save-dev
安装 stylelint 和标准配置插件。然后我创建了一个.stylelintrc文件并向其中添加了以下代码:
{
"extends": ["stylelint-config-standard"],
"rules": {
"rule-empty-line-before": "always",
"comment-empty-line-before": "always"
}
}
Run Code Online (Sandbox Code Playgroud)
npx stylelint \"src/app/**/*.{css,scss}\"当从终端运行以下命令时,我注意到一切运行良好,但当我在 Angular 项目中使用 scss 时,我看到了一些错误。为了防止这些基于 scss 的错误,我决定引入该stylelint-config-standard-scss插件。我使用 npm 安装了它,然后将文件中的代码更新.stylelintrc为以下内容:
{
"extends": [
"stylelint-config-standard",
"stylelint-config-standard-scss"
],
"rules": {
"rule-empty-line-before": "always",
"comment-empty-line-before": "always"
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当我运行命令时,npx stylelint \"src/app/**/*.{css,scss}\"出现以下错误!
TypeError: Class extends value undefined is not a constructor or null
at Object.<anonymous> (/Users/myuser/my-project/node_modules/postcss-scss/lib/nested-declaration.js:3:33)
at Module._compile (/Users/myuser/my-project/node_modules/v8-compile-cache/v8-compile-cache.js:192:30)
at Object.Module._extensions..js …Run Code Online (Sandbox Code Playgroud) 我知道有很多这样的问题,但它们经常让我感到困惑,或者让我很难应用到我的情况,所以我在这里问,这样我就可以把它放在我的脑海里。在我的组件打字稿文件中,我有一个方法调用使用 http 返回 api 数据的服务,因此当用户单击界面上的芯片时,他们会调用以下内容。
fetchCounts(filters?: any): void {
this.loaded = false;
this.apiCall = this.api.getCounts(filters).subscribe((results: any) => {
// do something with the returned data
this.loaded = true;
this.apiCall.unsunscribe()
});
}
Run Code Online (Sandbox Code Playgroud)
我的 api 服务如下所示:
getCounts(filters?: any): Observable<any> {
let params: any;
if (filters?.car?.length || filters?.bike?.length) {
params = this.addObjectToParams(new HttpParams(), filters);
}
return this.http.get('api/counts', { params } )
.pipe(map(this.extractData));
}
Run Code Online (Sandbox Code Playgroud)
现在我注意到,当用户单击我的界面添加和删除进行 API 调用的芯片时,由于过载/大量 API 调用,界面似乎不再显示真实数据。因此,如果进行新的调用(如果fetchCounts再次调用),我想取消当前的 api/http 调用。我尝试在getCounts方法中向 .pipe 添加去抖,就像这样.......pipe( debounceTime(500), map(this.extractData));但它似乎没有做任何事情。我想我必须添加一个switchMap,但是当我添加代码时,由于我缺乏理解,它就会中断。我目前正在查看文档...但任何帮助将不胜感激。
我是编码的新手,也是Angular的新手,所以我想寻求帮助。这是我的第一个问题,请耐心等待。
我想为Angular Material Dialog Service创建包装服务(我只是想教自己-不适用于生产应用程序),所以我在应用程序中创建了一个服务,如下所示:
import {Injectable} from '@angular/core';
import {MatDialog} from '@angular/material';
@Injectable({
providedIn: 'root'
})
export class MatDialogWrapperService {
constructor(private dialog: MatDialog) {
}
open(componentRef, config = {}) {
this.dialog.open(componentRef, config);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我尝试将其添加到应用程序中的另一个角度组件中,如下所示:我将其导入,添加到providers数组,将其放入构造函数中,然后将其放入方法中(为了方便起见,我删除了一些代码阅读)
@Component({
selector: 'app-intro-form',
templateUrl: './intro-form.component.html',
providers: [MatDialogWrapperService],
styleUrls: ['./intro-form.component.scss']
})
constructor(private modalService: MatDialogWrapperService ) {
}
modalCall() {
this.modalService.open(ModalFormComponent, {
width: '500px'
});
}
Run Code Online (Sandbox Code Playgroud)
加载应用程序时,我在控制台中看到以下错误:
未处理的承诺拒绝:StaticInjectorError(AppModule)[MatDialogWrapperService-> MatDialog]:StaticInjectorError(Platform:core)[MatDialogWrapperService-> MatDialog]:
NullInjectorError:MatDialog没有提供程序!; 区域:任务:Promise.then; 值:错误:StaticInjectorError(AppModule)[MatDialogWrapperService-> MatDialog]:StaticInjectorError(平台:核心)[MatDialogWrapperService-> MatDialog]:
我以为我已经将MatDialog正确地注入了包装服务中?我究竟做错了什么?
提前致谢。
我最近从我的 angular 项目中删除了 tslint - 我读到它已经贬值了,所以我想我最好把手弄脏并切换到 eslint。
所以我删除了 tslint 文件,跑去ng add @angular-eslint/schematics安装 lint 原理图,安装了 airbnb typescript linter,修改了ng lint任务以这样运行......
"lint": "eslint -c .eslintrc.js --ext .ts ./src/app"
Run Code Online (Sandbox Code Playgroud)
我添加了一个.eslintrc.js文件并用以下内容填充它
module.exports = {
root: true,
extends: [
'airbnb-typescript/base',
'plugin:@angular-eslint/recommended'
],
ignorePatterns: [
'node_modules/',
'build/',
'dist/',
'e2e/'
],
rules: {
'comma-dangle': ['error', 'only-multiline'],
'max-len': ['error', {code: 120, tabWidth: 4}],
'no-underscore-dangle': 'off',
'no-await-in-loop': 'off',
'import/prefer-default-export': 'off',
'no-param-reassign': ['error', {props: false}],
'strict': ['error', 'global'],
'func-names': 'off', // I use a lot …Run Code Online (Sandbox Code Playgroud) 我对 Angular 还很陌生,我的问题可能看起来很基本,但如果能提供一些指导,我将不胜感激。我目前正在编写一个应用程序来自学一些真正的开发技能。在我的应用程序中,我有一个 Angular 组件,它导入我编写的提供数据的服务。
这是我的组件
@Component({
selector: 'music-instrument-list',
templateUrl: './instrument-report.component.html',
styleUrls: ['./instrument-report.component.css']
})
export class InstrumentReportComponent implements OnInit, OnDestroy {
constructor(public apiService: ApiService) {}
public availableInstruments: any[];
ngOnInit() {
this.apiService.getInstruments().subscribe((result) => {
this.availableInstruments = result;
});
}
ngOnDestroy() {
// how do I unsubscribe?
}
}
Run Code Online (Sandbox Code Playgroud)
这非常简单,但如果我尝试添加this.apiService.getInstruments.unsubscribe()到ngOnDestroy块中,我会收到以下错误:Type => Observable' 上不存在 Property 'unsubscribe'。我什至考虑过在类似链接.unsubscribe()之后添加.subscribe(),但这只会使我的页面挂起。我也没有收到任何错误。有人可以告诉我如何最好地取消订阅吗?我是否需要将 api 调用分配给变量,然后在块中的变量名称上使用 .unsubscribe( ngOnDestroy)