如何在 Angular 中使用 zone.js?

Ite*_*tor 3 javascript zone angular

I would like to use zone.js in my Angular project ( not just the runOutsideAngularZone function ).

I tried to include it like this:

import { zone } from 'zone.js';
Run Code Online (Sandbox Code Playgroud)

Unfortunately I get this error:

error TS2306: File 'C:/projects/MyApp/node_modules/zone.js/dist/zone.js.d.ts' is not a module.
Run Code Online (Sandbox Code Playgroud)

Then I removed the { zone } part:

import 'zone.js';
Run Code Online (Sandbox Code Playgroud)

But now I get this error:

error TS2552: Cannot find name 'zone'. Did you mean 'Zone'?
Run Code Online (Sandbox Code Playgroud)

My code is this:

    let myZoneSpec = {
        beforeTask: function () {
            console.log('Before task');
        },
        afterTask: function () {
            console.log('After task');
        }
    };
    let myZone = zone.fork(myZoneSpec);
    myZone.run(() => {console.log('Task');});
Run Code Online (Sandbox Code Playgroud)

If I replace ?one with Zone, I get this:

error TS2339: Property 'fork' does not exist on type 'ZoneType'.
Run Code Online (Sandbox Code Playgroud)

How could I import and use zone.js from Angular?

Sha*_*aiz 6

角有一个包装类Zone.js称为ngZone。您可以像任何服务一样将其注入到您的组件中。

    constructor(private zone: NgZone) { 
       this.zone.run(() => { console.log('This is zone'});
     }
Run Code Online (Sandbox Code Playgroud)

但是,使用这种方法,我们无法使用zone.js的全部功能。为此,我们必须声明:

declare let Zone: any;
public class MyComponent {
  constructor() {
        Zone.current.fork({
            name: 'myZone'
          }).run(() => {
            console.log('in myzone? ', Zone.current.name);
          });
    }
}
Run Code Online (Sandbox Code Playgroud)

此外,自 0.6.0 版以来,API 也发生了变化。对于运行 beforeTask 和 afterTask,您可以在此处查看,但是,我查看了它并找不到与beforeTaskafterTask相关的任何内容

更新
为了运行beforeTaskafterTask,这就是新 API 中的可能方式。

constructor() {
    const parentZone = new Zone();
    const childZone = parentZone.fork({
      name: 'child',
      onInvoke: (...args) => { 
                 console.log('invoked\n', args);
                 const valueToReturn = args[3](); // Run the function provided in the Zone.run
                 console.log('after callback is run');
                 return valueToReturn;
              }
    });
   console.log(childZone.run(() => {console.log('from run'); return 'from child run';}));

}
Run Code Online (Sandbox Code Playgroud)

注意:
如果您想创建一个scheduleMicroTask并希望在其中拥有相同的功能,那么您需要在 ZoneSpec(在 parentZone.fork() 内)实现onInvokeTask和/或onScheduleTask

constructor() {
   const parentZone = new Zone();
    const childZone = parentZone.fork({
      name: 'child',
      onScheduleTask: (...args) => {
        console.log('task schedule...\n', args);
        return args[3];
      },
      onInvokeTask: (...args) => {
        console.log('task invoke...\n', args);
        return args[3].callback();
      }
    });

    const microTask = childZone
                      .scheduleMicroTask(
                        'myAwesomeMicroTask',
                        () => { 
                                console.log('microTask is running'); 
                                return 'value returned from microTask'; 
                            } );
    console.log(microTask.invoke());
}
Run Code Online (Sandbox Code Playgroud)