2017-06-13 104 views
4

一位同事聲稱,這是將純ES6 JavaScript類注入Angular的不正確方法。我很好奇,如果有更好的方法(更正確)?順便說一下,將注入的依賴關係(本例中爲$timeout)附加到實例上會更好嗎?爲什麼它更好?例如,構造函數中的this._$timeout = $timeout。我個人認爲在這種情況下做這件事沒有任何好處。在ES6中將純類注入到角度1.x應用程序中的正確方法

class.factory.js

let ClassFactory = function($timeout) { 
    // Factory function that simply returns class constructor. 

    class MyClass { 
     constructor(a, b) { 
      // contrived class 
      this.a = a; 
      this.b = b; 
      this.c = null; 
     } 

     applyChange() { 
      // contrived class method 
      const SELF = this; 

      $timeout(() => { 
       SELF.c = SELF.a + SELF.b; 
      }); 
     } 
    } 

    return MyClass ; 
}; 

ClassFactory.$inject = ['$timeout']; 

export default ClassFactory; 

app.module.js

import ClassFactory from './factories/class.factory'; 
import AppService from './services/app.service'; 


export default angular.module('myApp', []) 
    .factory('ClassFactory', ClassFactory) 
    .service('AppService', AppService); 

後來,在其他地方,我們可以使用類的一些服務或控制器,構建新MyClass的實例。

app.service.js

class AppService { 
    // contrived usage of our dependency injected pure class. 

    constructor(ClassFactory) { 
     this.array = []; 
     this._ClassFactory = ClassFactory; 
    } 

    initialize(a, b) { 
     // We can instantiate as many "MyClass" objects as we need. 
     let myClass = new this._ClassFactory(a, b); 

     this.array.push(myClass); 
    } 

    static serviceFactory(...injected) { 
     AppService.instance = new AppService(...injected); 
     return AppService.instance; 
    } 
} 

AppService.serviceFactory.$inject = ['ClassFactory']; 

export default AppService.serviceFactory; 
+1

像AppService.instance = new AppService這樣的事情也不可取。它可能會正常工作,因爲只有1個應用程序實例,而服務是單例。但是它會在測試過程中導致內存泄漏。 – estus

回答

3

此時如果$timeout是類屬性或只是局部變量沒關係。

使用工廠函數包裝類在ES6開發中不能很好地發揮作用,因此無法導出和擴展它。需要工廠的事實可能表明設計問題。

類似這樣的類可以通過依賴注入獲取依賴關係(在common sense中)。這是一個平常的事情,當類的構造應該與非依賴性的參數也被稱爲:

export class MyClass { 
    constructor($timeout, a, b) { 
    this._$timeout = $timeout; 
    ... 
    } 
} 
... 
obj = new MyClass($timeout, a, b); 

如果有一個以上的依賴,$injector依賴性可以代替提供的所有依賴:

export class MyClass { 
    constructor($injector, a, b) { 
    this._$timeout = $injector.get('$timeout'); 
    ... 
    } 
} 
... 
obj = new MyClass($injector, a, b); 

也可能有一個設計問題導致依賴於$timeout,並通過解決它可以避免依賴。從上面的代碼中不清楚爲什麼MyClass應該觸發$timeout的摘要,其邏輯不包含任何需要的內容。代碼的責任是使用MyClass實例並將其綁定到查看或任何摘要。

+0

這是一個人爲的例子。但在實際的課堂中,我們需要訪問一些Angular功能。 '$ timeout'的真正用處是觸發一個Angular digest循環(在狹義條件下),所以類實例中的變化會傳播。 – James

+0

你可以舉一個例子來說明在我們的例子中使用'$ injector'嗎?對於您的其他評論,我沒有找到任何解釋如何在Angular上使用純ES6類的好資源。使用工廠返回課程是我能找到的最接近的東西。 – James

+1

@TechMedicNYC已添加。是的,這是比較低調的情況,而不是通常在指南中討論的情況。工廠功能是在非模塊化ES5中完成的方式,但對於ES6來說,它看起來不夠好。 – estus

相關問題