如何编写代理函数?实现类方法带/不带ngZone.run包装执行
问题描述
现有一个包含多个方法的类,其中drawGeojson方法实现如下:
drawGeojson(layerid: string, geojsonObject) { this.ngZone.run(() => { // 原有方法逻辑 }); }
需要重构代码,实现按需选择是否通过this.ngZone.run(() => {})包装器执行方法体,同时满足:
- 默认调用方式:直接调用
drawGeojson()(无需包装器) - 代理调用方式:通过
Wrapper.drawGeojson()执行带包装器的逻辑
重构方案
方案1:可选参数控制包装器开关
将核心逻辑抽离,通过可选参数决定是否启用包装,同时实现静态代理类:
class YourMapClass { // 抽离核心业务逻辑为私有方法 private _drawGeojson(layerid: string, geojsonObject) { // 这里放置原方法内的业务代码 console.log('绘制GeoJSON:', layerid, geojsonObject); } // 默认调用:直接执行核心逻辑(默认不启用包装器) drawGeojson(layerid: string, geojsonObject, useNgZone = false) { if (useNgZone) { this.ngZone.run(() => this._drawGeojson(layerid, geojsonObject)); } else { this._drawGeojson(layerid, geojsonObject); } } // 静态代理类:统一处理带包装器的调用 static Wrapper = class { constructor(private instance: YourMapClass) {} drawGeojson(layerid: string, geojsonObject) { this.instance.ngZone.run(() => this.instance._drawGeojson(layerid, geojsonObject)); } }; } // 使用示例 const mapInstance = new YourMapClass(); // 默认调用(无包装器) mapInstance.drawGeojson('layer1', geojsonData); // 代理调用(带包装器) const wrapper = new YourMapClass.Wrapper(mapInstance); wrapper.drawGeojson('layer1', geojsonData);
方案2:拆分独立方法+静态代理
如果不想修改原方法参数,直接拆分出带包装器的独立方法,通过代理类暴露:
class YourMapClass { private _drawGeojson(layerid: string, geojsonObject) { // 核心业务逻辑 console.log('绘制GeoJSON:', layerid, geojsonObject); } // 默认调用:无包装器 drawGeojson(layerid: string, geojsonObject) { this._drawGeojson(layerid, geojsonObject); } // 带包装器的内部方法 private _drawGeojsonWithZone(layerid: string, geojsonObject) { this.ngZone.run(() => this._drawGeojson(layerid, geojsonObject)); } // 静态代理类 static Wrapper = class { constructor(private instance: YourMapClass) {} drawGeojson(layerid: string, geojsonObject) { this.instance._drawGeojsonWithZone(layerid, geojsonObject); } }; } // 使用示例 const mapInstance = new YourMapClass(); // 默认调用 mapInstance.drawGeojson('layer1', geojsonData); // 代理调用 const wrapper = new YourMapClass.Wrapper(mapInstance); wrapper.drawGeojson('layer1', geojsonData);
方案3:装饰器实现批量包装(多方法场景)
如果类内多个方法都需要按需包装能力,用装饰器简化重复代码:
// 定义NgZone包装装饰器 function withNgZone(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; descriptor.value = function(...args: any[]) { this.ngZone.run(() => originalMethod.apply(this, args)); }; return descriptor; } class YourMapClass { // 默认调用:无包装器 drawGeojson(layerid: string, geojsonObject) { // 核心业务逻辑 console.log('绘制GeoJSON:', layerid, geojsonObject); } // 带包装器的版本(供代理调用) @withNgZone private drawGeojsonWithZone(layerid: string, geojsonObject) { this.drawGeojson(layerid, geojsonObject); } static Wrapper = class { constructor(private instance: YourMapClass) {} drawGeojson(layerid: string, geojsonObject) { this.instance.drawGeojsonWithZone(layerid, geojsonObject); } }; }
内容的提问来源于stack exchange,提问作者Araviz
相关产品推荐
相关产品推荐

