我的Angular5应用程序在应用程序初始化期间从后端加载配置文件(APP_INITIALIZER).由于应用程序无法在没有它的情况下运行,我的目标是向用户显示无法加载配置的消息.
providers: [ AppConfig,
{ provide: APP_INITIALIZER, useFactory: (config: AppConfig) => () => config.load(), deps: [AppConfig], multi: true },
{ provide: LocationStrategy, useClass: HashLocationStrategy},
{ provide: ErrorHandler, useClass: GlobalErrorHandler }]
Run Code Online (Sandbox Code Playgroud)
该AppConfig
班应该加载从应用程序加载之前的后端服务的配置文件:
@Injectable()
export class AppConfig {
private config: Object = null;
constructor(private http: HttpClient) {}
public getConfig(key: any) {
return this.config[key];
}
public load() {
return new Promise((resolve, reject) => {
this.http.get(environment.serviceUrl + 'config/config')
.catch((error: any) => {
return Observable.throw(error || 'Server error');
})
.subscribe((responseData) => {
this.config …
Run Code Online (Sandbox Code Playgroud) 我最近构建了以下Angular 2 Read More组件.该组件所做的是使用"Read more"和"Read less"链接折叠和扩展长文本块.不是基于字符数,而是基于指定的最大高度.
import { Component, Input, ElementRef, AfterViewInit } from '@angular/core';
@Component({
selector: 'read-more',
template: `
<div [innerHTML]="text" [class.collapsed]="isCollapsed" [style.height]="isCollapsed ? maxHeight+'px' : 'auto'">
</div>
<a *ngIf="isCollapsable" (click)="isCollapsed =! isCollapsed">Read {{isCollapsed? 'more':'less'}}</a>
`,
styles: [`
div.collapsed {
overflow: hidden;
}
`]
})
export class ReadMoreComponent implements AfterViewInit {
//the text that need to be put in the container
@Input() text: string;
//maximum height of the container
@Input() maxHeight: number = 100;
//set these to false to …
Run Code Online (Sandbox Code Playgroud) 有这个 Angular 组件:
import { Component, OnDestroy, OnInit } from '@angular/core';
import { asyncScheduler, Observable, of, queueScheduler, scheduled } from 'rxjs';
@Component({
selector: 'test-component',
templateUrl: './test-component.component.html'
})
export class TestComponentComponent implements OnInit {
value: string;
constructor() { }
ngOnInit(): void {
const data$ = this.fetchDataScheduler();
data$
.subscribe(value => {
this.value = value;
});
}
private fetchDataScheduler(): Observable<string> {
return scheduled(of('foo'), asyncScheduler);
}
}
Run Code Online (Sandbox Code Playgroud)
并且测试失败:
it('async - test setTimeout', fakeAsync(() => {
expect(component.value).toBeFalsy();
fixture.detectChanges(); // ngOnInit
expect(component.value).toBeFalsy();
flush();
expect(component.value).toBe('foo'); // <- …
Run Code Online (Sandbox Code Playgroud) 我有一个带有 Jest 的 Angular 应用程序,所有测试都运行良好。组件注入服务:
组件.ts:
import { FooService } from '../../services/foo.service'; // relative import
constructor(private foo: FooService) {}
Run Code Online (Sandbox Code Playgroud)
组件规格:
import { FooService } from '@services/foo.service'; // alias import
describe('FooComponent', () => {
let component: FooComponent;
let fixture: ComponentFixture<FooComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [....],
providers: [ { provide: FooService, useValue: { bar: () => {} } ],
declarations: [FooComponent],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
....
}));
});
Run Code Online (Sandbox Code Playgroud)
两个导入引用相同 foo.service.ts
,但使用不同形式的导入:TypeScript 别名vs相对路径。
别名在 tsconfig.json 中定义:
"paths": …
Run Code Online (Sandbox Code Playgroud) when(validator.isValid(Sets.newHashSet("valid"))).thenReturn(true);
Run Code Online (Sandbox Code Playgroud)
当validator.isValid(set)
被调用时它返回false。这是因为验证器实现创建了一个与传递的不同的新集合(引用不同)——两个集合中的项目是相同的。
如果集合包含相同的项目,无论集合实例如何,我都需要返回true。
类似于org.mockito.Matchers
:
public static <T> Set<T> anySetOf(Class<T> clazz) {
return (Set) reportMatcher(Any.ANY).returnSet();
}
Run Code Online (Sandbox Code Playgroud)
除了我不会通过实例之外Class<T>.class
。
和同样的verify
:
verify(validator, times(1)).isValid(Sets.newHashSet("valid"));
Run Code Online (Sandbox Code Playgroud)
有这样的匹配器吗?
我有两个角度模块:main和feature:
主/根模块:
@NgModule({
imports: [
StoreModule.forRoot({router: routerReducer}),
EffectsModule.forRoot([...]),
...
],
declarations: [],
...
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)
功能模块:
@NgModule({
imports: [
StoreModule.forFeature('feature', {someValue: someValueReducer}),
EffectsModule.forFeature([...]),
...
],
declarations: [],
...
})
export class FeatureModule {}
Run Code Online (Sandbox Code Playgroud)
我需要访问主模块中的“功能”数据切片,以基于feature
模块中存储的数据有条件地显示/激活应用程序选项卡。
(换句话说,我需要所有主模块和任何功能模块都可以访问的全局/共享状态。)
目前,我无法执行此操作,因为feature
main中没有状态AppState
:
export interface AppState {
router: RouterReducerState<RouterStateUrl>;
}
Run Code Online (Sandbox Code Playgroud)
this.store.select('feature')
由于没有feature
主存储键,打字稿表示错误AppState
。
使用selector
:this.store.select(selectFeatureValue)
我遇到运行时错误:
export const selectFeatureModule = createFeatureSelector<FeatureState>('feature');
export const …
Run Code Online (Sandbox Code Playgroud) 有一个简单的(Angular 4)路由守卫,它等待从后端加载一些数据:
@Injectable()
export class ContractsLoadedGuard implements CanActivate {
constructor(private store: Store<State>) { }
waitForData(): Observable<boolean> {
return this.store.select(state => state.contracts)
.map(contractList => !!contractList)
.filter(loaded => loaded)
.take(1);
}
canActivate(): Observable<boolean> { return this.waitForData(); }
}
Run Code Online (Sandbox Code Playgroud)
路由:
const routes: Routes = [
{ path: 'app-list', canActivate: [ContractsLoadedGuard], component: AppListComponent },
];
Run Code Online (Sandbox Code Playgroud)
最后还有一个由@ngrx/router-store v4ROUTER_NAVIGATION
动作触发的@ngrx/effects :
@Effect() routeChange$ = this.actions$
.ofType(ROUTER_NAVIGATION)
.filter((action: RouterNavigationAction) => action.payload.routerState.url.indexOf('/app-list') > -1)
.withLatestFrom(this.store.select(state => state.contracts))
.switchMap(([action, contracts]: ([RouterNavigationAction, ContractList])) =>
this.restClient.load(action.payload.routerState.queryParams, contract));
Run Code Online (Sandbox Code Playgroud)
不幸的是,当导航更改为/app-list
ngrx …
我已将jasmine-marbles添加到我的项目中,但收到如下错误消息:
Expected $[0].frame = 20 to equal 70.
Expected $[0].notification.kind = 'E' to equal 'N'.
Expected $[0].notification.value = undefined to equal LoadSuccess().
Run Code Online (Sandbox Code Playgroud)
而不是这样的:
Expected
{"frame":50,"notification":{"kind":"N","value":{"payload":"[
...
to deep equal
{"frame":40,"notification":{"kind":"N","value":{"payload":"[
...
Run Code Online (Sandbox Code Playgroud)
测试:
it('should loadData$', () => {
const action = new LoadRequest('123');
const completion = new LoadSuccess({});
actions$.stream = hot('-a', { a: action });
const response = cold('-a|', { a: {} });
const expected = cold('---c', { c: completion });
client.loadData = () => response;
expect(effects.loadData$).toBeObservable(expected);
});
Run Code Online (Sandbox Code Playgroud)
包.json: …
我想将 Angular 源代码/源映射附加到我生成的 Angular CLI 项目中,以便我可以像*ngIf
在 Chrome 中一样调试指令。
是否可以以某种方式将调试器附加到ng_if.ts
使用某些 angular.json 配置/源映射...?或者是否有一个设置可以在开发模式下添加源映射,以便我可以单步执行任何带有源映射的第三方库?
如果我在Chrome中按Ctrl+O然后输入,ngIf
或者ng_if
列表菜单中没有这样的文件。
编辑:提供供应商源映射时的样子(请参阅接受的答案):
切换到Ivy 编译器后出现Typescript 错误:
[Step 4/5] src/app/app.component.html(1,26): Type 'SafeHtml' is not assignable to type 'string'.
Run Code Online (Sandbox Code Playgroud)
在 Angular 类中,有一个成员属性声明为SafeHtml
:
@Component({
selector: 'app',
template: `<div [innerHTML]="description"></div>`
})
export class AppComponent {
description: SafeHtml;
constructor(private sanitizer: DomSanitizer) {}
ngOnInit(): void {
this.description = this.sanitizer.sanitize(SecurityContext.HTML, '<strong>whatever comes from server</strong>');
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是如何转换SafeHtml
和SafeUrl
字符串?就这样就.toString()
OK了吗?
AngularsSafeHtml
声明为:
/**
* Marker interface for a value that's safe to use as HTML.
*
* @publicApi
*/
export …
Run Code Online (Sandbox Code Playgroud) angular ×7
typescript ×6
rxjs ×2
angular-ivy ×1
angular-test ×1
debugging ×1
jasmine ×1
java ×1
matcher ×1
mocha.js ×1
mockito ×1
ngrx ×1
ngrx-effects ×1
set ×1
source-maps ×1
webstorm ×1