我在Angular项目中遇到一个错误,该错误最终通过将代码包装到
this.zone.run(() => {/* my code here */});
Run Code Online (Sandbox Code Playgroud)
如该答案所述。
我以前的理解zone
是angular无法检测到异步callbacks
第三方库所做的更改,因为“它们不在angular的范围内zone
”。如果我单击a button
,则触发的事件不是浏览器的本机click
事件,而是click
由angular创建的自定义(修补)事件,其handler
在zone
so angular中的运行会意识到其回调处理程序所做的更改。
但是我无法理解通过router.navigate()
在第三方回调中运行来创建此问题(如此 github问题所示)。是不是Router
一个service
角本身?为什么zone
在第三方中调用时,它不会自动通知angular callback
?
我通过router.navigate
在NGXS的状态缩减器中使用来解决此问题。
我的问题是:
有人可以解释我到底什么时候需要包装我的代码NgZone
?
调试了几个小时,意识到我的代码没有zone
上下文,这很烦人。
我最近将我公司的网站从React迁移到了Angular,因为我们的大多数项目都已经在Angular 7上了.作为"使用 - 最新和最伟大"的人,我决定实现服务器端渲染获得谷歌网页速度评级接近100/100(目前为42/100).我一直在修补这个星期的大部分时间,但没有成功 - 最新的障碍对我来说特别难以克服.这是关于我的设置的简要信息,然后我会详细介绍:
当我尝试渲染为SSR设置的layout.html文件时,这是我得到的错误:
TypeError: Cannot read property 'subscribe' of undefined
at new ApplicationRef (C:\code\lemmsoftWebsite\repo\public\site\serverBuild\main.js:43263:37)
at _createClass (C:\code\lemmsoftWebsite\repo\public\site\serverBuild\main.js:46296:20)
at _createProviderInstance (C:\code\lemmsoftWebsite\repo\public\site\serverBuild\main.js:46258:26)
at initNgModule (C:\code\lemmsoftWebsite\repo\public\site\serverBuild\main.js:46190:32)
at new NgModuleRef_ (C:\code\lemmsoftWebsite\repo\public\site\serverBuild\main.js:46918:9)
at createNgModuleRef (C:\code\lemmsoftWebsite\repo\public\site\serverBuild\main.js:46907:12)
at Object.debugCreateNgModuleRef [as createNgModuleRef] (C:\code\lemmsoftWebsite\repo\public\site\serverBuild\main.js:48738:12)
at NgModuleFactory_.module.exports.NgModuleFactory_.create (C:\code\lemmsoftWebsite\repo\public\site\serverBuild\main.js:49466:25)
at C:\code\lemmsoftWebsite\repo\node_modules\@angular\core\bundles\core.umd.js:14656:47
at ZoneDelegate.module.exports.ZoneDelegate.invoke (C:\code\lemmsoftWebsite\repo\public\site\serverBuild\main.js:139510:26)
at Object.onInvoke (C:\code\lemmsoftWebsite\repo\node_modules\@angular\core\bundles\core.umd.js:14194:37)
at ZoneDelegate.module.exports.ZoneDelegate.invoke (C:\code\lemmsoftWebsite\repo\public\site\serverBuild\main.js:139509:32)
at Zone.module.exports.Zone.run (C:\code\lemmsoftWebsite\repo\public\site\serverBuild\main.js:139260:43)
at NgZone.run (C:\code\lemmsoftWebsite\repo\node_modules\@angular\core\bundles\core.umd.js:14108:32)
at PlatformRef.bootstrapModuleFactory (C:\code\lemmsoftWebsite\repo\node_modules\@angular\core\bundles\core.umd.js:14654:27)
at renderModuleFactory (C:\code\lemmsoftWebsite\repo\node_modules\@angular\platform-server\bundles\platform-server.umd.js:1033:43)
at View.module.app.engine (C:\code\lemmsoftWebsite\repo\modules\clients\site\layout\index.js:60:4) …
Run Code Online (Sandbox Code Playgroud) 我有一个使用Angular Google Maps来显示位置的应用程序.一开始我能够显示地图,但是一段时间(可能是我修改了一些东西)我收到以下错误:
ERROR Error: Uncaught (in promise): Error: StaticInjectorError[NgZone]:
StaticInjectorError[NgZone]:
NullInjectorError: No provider for NgZone!
at _NullInjector.get (core.js:923)
at resolveToken (core.js:1211)
at tryResolveToken (core.js:1153)
at StaticInjector.get (core.js:1024)
at resolveToken (core.js:1211)
at tryResolveToken (core.js:1153)
at StaticInjector.get (core.js:1024)
at resolveNgModuleDep (core.js:10585)
at NgModuleRef_.get (core.js:11806)
at resolveDep (core.js:12302)
at _NullInjector.get (core.js:923)
at resolveToken (core.js:1211)
at tryResolveToken (core.js:1153)
at StaticInjector.get (core.js:1024)
at resolveToken (core.js:1211)
at tryResolveToken (core.js:1153)
at StaticInjector.get (core.js:1024)
at resolveNgModuleDep (core.js:10585)
at NgModuleRef_.get (core.js:11806)
at resolveDep (core.js:12302)
at resolvePromise (zone.js:824)
at …
Run Code Online (Sandbox Code Playgroud) 对 requestAnimationFrame 进行单元测试的方法有哪些?
requestAnimationFrame 与 setTimeout/setInterval 具有相同的性质。它也由 zone.js 修补,就像 fn 的 setTimeout 一样被修补。所以我首先想到的选项是
结果:
这是方法:
reqAnimFrame() {
requestAnimationFrame(() => {
console.log('log stuff');
this.title = 'req frame title';
});
}
Run Code Online (Sandbox Code Playgroud)
这是单元测试(工作单元测试):
it('fakeAsync', fakeAsync(function () {
const fixture = TestBed.createComponent(AppComponent);
const app: AppComponent = fixture.debugElement.componentInstance;
fixture.detectChanges();
app.reqAnimFrame(); …
Run Code Online (Sandbox Code Playgroud)
我想在蓝牙连接完成后执行一些操作,反之亦然.
处理连接的方案,并添加成功和失败处理程序,并在这些处理程序函数中将标志更改为True和False.
我使用console.log打印了该值,它在组件文件中更改但未反映在HTML中.
我尝试过使用ngZone,但它没有用.
成功和失败处理代码如下:
BluetoothService
import { Injectable } from "@angular/core";
import { BLE } from '@ionic-native/ble';
@Injectable()
export class BlueToothService {
constructor(private ble: BLE){
}
public connect = (deviceId, onConnect, onFailure) => {
this.ble.isConnected(deviceId)
.then(response => {
onConnect(response);
},
error => {
this.ble.connect(deviceId)
.subscribe(response => {
onConnect(response);
},
error => {
onFailure(error);
});
});
} }
Run Code Online (Sandbox Code Playgroud)
组件文件
import {Component, NgZone} from '@angular/core';
import {Events, IonicPage, NavController, NavParams, ViewController} from 'ionic-angular';
import {BlueToothService} …
Run Code Online (Sandbox Code Playgroud) 我创建了一个 Angular 6 库,但是当我尝试在创建它的项目之外使用它时出现错误。这看起来像很多代码,但它主要是由 CLI 生成的样板。
我使用 Angular 6 CLI 创建了一个非常基本的库。
ng new mylib
cd mylib
ng generate library example
ng build --prod example
Run Code Online (Sandbox Code Playgroud)
然后,我可以添加 <lib-example></lib-example>
到src/app/app.component.html
、运行ng serve
并查看示例组件按预期工作。
接下来我编辑projects/example/src/lib/example.component.ts
添加一个 an*ng-if="true"
到<p>
标签。
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'lib-example',
template: `
<p *ng-if="true"> <!-- this line was changed -->
example works!
</p>
`,
styles: []
})
export class ExampleComponent implements OnInit {
constructor() { }
ngOnInit() { …
Run Code Online (Sandbox Code Playgroud) 我将如何对以下组件进行茉莉花测试:
@Component({
moduleId: module.id,
selector: "testComp",
template: "<div>{{value}}</div>",
})
export class TestComp {
public value: string = "This is me";
constructor(public zone: NgZone) {
this.zone.run(() => console.log("zone is here"));
}
}
Run Code Online (Sandbox Code Playgroud)
由于无法解析NgZone的所有参数,以下操作失败:
describe("test", () => {
let fixture;
let component;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TestComp],
schemas: [NO_ERRORS_SCHEMA],
providers: [NgZone]
}).compileComponents;
}));
beforeEach(() => {
fixture = TestBed.createComponent(TestComp);
component = fixture.debugElement.componentInstance;
});
it("should check that the component is created", () => {
expect(component).toBeTruthy();
});
Run Code Online (Sandbox Code Playgroud)
})
使用Angular 4.1.3。我发现了MockNgZone类@ https://no-shadow-angular-io.firebaseapp.com/docs/ts/latest/api/core/testing/MockNgZone-class.html。但是对于此特定版本,在@ angular …
我最近按照本指南学习如何创建角度库并将其发布供我自己使用:https://medium.com/@nikolasleblanc/building-an-angular-4-component-library-with-the-angular- cli-and-ng-packagr-53b2ade0701e
打包该库并从我自己的 Angular 项目中引用它后,我出现了以下错误:NullInjectorError:没有 NgZone 的提供程序。
当我尝试在我的控制器中注入 NgZone 时,而不引用我的库中也注入它的组件,我的项目运行得很好。但是,当我尝试引用我看来的库组件时,它不再起作用!
我花了一整天的时间试图解决这个问题,但是几乎没有关于这个错误的信息,我相信它与 NgZone 无关,而是我忽略的东西。
我不确定我应该提供什么样的信息来更好地解决此错误,所以请随时询问我。
我的库和项目都引用了 Angular 5.0.0 和 zone.js 0.8.12。您可以在 github 上找到我发布的库:https ://github.com/lakylekidd/skating-library
任何帮助将不胜感激,它让我发疯!
提前谢谢你,比利
我有一个一般性的角度问题:
为什么async
使用角管cdr.markForCheck()
而不是cdr.detectChanges()
?
我认为这两种“风格”有两个主要区别:
markForCheck()
标记要检查的路径直到根组件 -要更新的内容markForCheck()
让变化检测发生在当前或下一个周期 -计时我的想法或问题:
为什么我们需要检查根的整个路径(在async
管道中)?为什么不只是当前组件?( ) - 这与要更新的内容detectChanges()
有关
为什么只标记(对于当前/下一个周期 - 使用markForCheck()
ngZone)?为什么不立即检测变化?( ) 这与时间detectChanges()
有关
如果没有 ngZone 异步触发器/没有异步操作怎么办?那么视图更新不会发生吗?
async
如果我们改为使用管道会发生什么detectChanges()
?
异步管道:
private _updateLatestValue(async: any, value: Object): void {
if (async === this._obj) {
this._latestValue = value;
this._ref.markForCheck();
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
async
请不要解释每种方法的作用,因为我在文档中阅读了很多次,并且从角度来看我无法理解。对我来说,重要的是要知道更新内容和时间安排的原因。
下面是在一个子组件上调用的更改函数,以更改selectedName
其他两个子组件中的@Input
字符串类型,如果我将其更改为对象,它可以正常工作。
angular ×10
ngzone ×10
zone.js ×2
angular-cli ×1
ionic3 ×1
jasmine ×1
javascript ×1
maps ×1
ngonchanges ×1
ssr ×1
typescript ×1
unit-testing ×1
webpack ×1