2017-08-30 36 views
0

我在我的angular 4項目中包含了cropper.js。 在組件我用cropper.js我註冊了自己的ready事件,像這樣:angular 4,zone.js和javascript庫的自定義事件

this.cropperOptions = { 
    // omitted options which are not importent 
    cropend:() => { 
     this.changedOrTouched(); 
    }, 
    ready:() => { 
     URL.revokeObjectURL(this.cropperImage.nativeElement.src); 
     this.photoReady.emit(); 
     this.changedOrTouched(); 
    } 
}; 

的emited ready事件是由自身通知服務父組件消耗

父組分

photoReady(): void { 
     this.loaderService.setLoaderStatus(false); 
    } 

服務

export class LoaderService { 
    public loaderStatus: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); 

    /** 
    * indicates wheter something in the application is loading or not. Internal it calls next() on the loaderStatus BehaviorSubject. 
    * This triggers any subscription to that BehaviorSubject which then can act. 
    * @param value true if application is loading, false if not. 
    */ 
    setLoaderStatus(value: boolean) { 
     this.loaderStatus.next(value); 
    } 
} 

一個非常簡單的服務,這app.component訂閱像這樣

app.component

this.loaderService.loaderStatus.subscribe((val: boolean) => { 
      this.isLoading = val; 
      //this is here because of iOS 
      this.changeDetector.detectChanges(); 
     }); 

它的作用是顯示或隱藏的好手。

幾乎每個瀏覽器都能按預期工作,當IE10被cropper.js就緒事件觸發時,IE10不會隱藏微調器。

儘管zone.js對我來說仍然是一個謎,有時候我會(有點)理解它是如何工作的。

我已經有類似的問題,這是我(或其他人)可以通過或者使用ChangeDetectorRef.detectChanges()NgZone.run()ApplicationRef.tick,或包裹在setTimeout電話通常修復。

已經嘗試過那些在各個地方無濟於事,我不明白爲什麼以上都沒有解決這個問題。 也許cropper.js以zone.js無法處理的方式添加事件? 也許有一種方法可以從外部js庫中修補自定義事件嗎?

任何想法?

下面是如何cropper.js增加了事件 cropper.js - 添加事件

function addListener(element, type, _handler, once) { 
    var types = trim(type).split(REGEXP_SPACES); 
    var originalHandler = _handler; 

    if (types.length > 1) { 
    each(types, function (t) { 
     addListener(element, t, _handler); 
    }); 
    return; 
    } 

    if (once) { 
    _handler = function handler() { 
     for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { 
     args[_key4] = arguments[_key4]; 
     } 

     removeListener(element, type, _handler); 

     return originalHandler.apply(element, args); 
    }; 
    } 

    if (element.addEventListener) { 
    element.addEventListener(type, _handler, false); 
    } else if (element.attachEvent) { 
    element.attachEvent('on' + type, _handler); 
    } 
} 

cropper.js - 調度事件

function dispatchEvent(element, type, data) { 
    if (element.dispatchEvent) { 
    var event = void 0; 

    // Event and CustomEvent on IE9-11 are global objects, not constructors 
    if (isFunction(Event) && isFunction(CustomEvent)) { 
     if (isUndefined(data)) { 
     event = new Event(type, { 
      bubbles: true, 
      cancelable: true 
     }); 
     } else { 
     event = new CustomEvent(type, { 
      detail: data, 
      bubbles: true, 
      cancelable: true 
     }); 
     } 
    } else if (isUndefined(data)) { 
     event = document.createEvent('Event'); 
     event.initEvent(type, true, true); 
    } else { 
     event = document.createEvent('CustomEvent'); 
     event.initCustomEvent(type, true, true, data); 
    } 

    // IE9+ 
    return element.dispatchEvent(event); 
    } else if (element.fireEvent) { 
    // IE6-10 (native events only) 
    return element.fireEvent('on' + type); 
    } 

    return true; 
} 

cropper.js - 叫ready事件

// Call the "ready" option asynchronously to keep "image.cropper" is defined 
     self.completing = setTimeout(function() { 
     if (isFunction(options.ready)) { 
      addListener(element, EVENT_READY, options.ready, true); 
     } 

     dispatchEvent(element, EVENT_READY); 
     dispatchEvent(element, EVENT_CROP, self.getData()); 

     self.complete = true; 
     }, 0); 
+0

你爲什麼不使用導航的'路由器導航events'會更容易維護檢查這個https://stackoverflow.com/a/38620817/2708210不參與 –

+0

路由,我怎麼看不到鏈接問題是相關的? – Arikael

回答

0

cropper.jszone.js工作的原因是cropper.js的addEventListener/removeEventListener not patched by zone.js , so it is not in ngZone`,你可以自己修補它。

  1. 更新zone.js到最新版本0.8。18
  2. 添加以下代碼

    Zone.__load_patch('cropper', function (global, Zone, api) { 
    // check cropper loaded or not 
    if (!global['cropper']) { 
        return; 
    } 
    api.patchEventTarget(global, [global['cropper'].prototype], { 
        addEventListenerFnName: 'addListener', removeEventListenerFnName: 
        'removeListener' }); 
    

    });

注:代碼假定種植者是一個全局對象,如果不是,請讓農作物類型,更換全球[「跟頭」]部分。