2015-07-11 43 views
1

我正在使用Angular 1.x的Web應用程序體系結構,仍然用於將事物粘合在一起。定義一個新的組件是相當容易:ES2015 + ES2016(裝飾,理解,...)+ Angular 1.x組件

class CustomComponent { 
    constructor(dep1, dep2, dep3) { 
    this.deps = { dep1, dep2, dep3 }; 
    /* app code */ 
    } 

    /* link, compile, instance methods, template generators... */ 

    @readonly static $inject = ['dep1', 'dep2', 'dep3']; 
} 

我希望做的是走出因子注射的擔憂 - 換句話說,我想不寫,每次this.depsstatic $inject代碼,而是讓它自動生成 - 比如在ES7中使用類似裝飾器的東西。然後,代碼將沿着以下的說法:

@injectionFromCtorComponents 
class MyClass { 
    constructor (dep1, dep2, dep3) { 
    /* app logic */ 
    } 
} 

現在,靜態部分是可行的,雖然難看:

const angularInjectAnnotationFromCtor = (target) => { 
    let regexStr = `^function ${target.name}\\\((.*)\\\)[.\\s\\S]*}$`; 
    let regex = new RegExp(regexStr, 'gm'); 
    let ctorArgsStr = target.prototype.constructor.toString().replace(regex, '\$1'); 
    let ctorArgs = ctorArgsStr.replace(/ /g, '').split(','); 

    target.$inject = ctorArgs; 
}; 

上的實例構造函數依賴的儲蓄,不過,很多棘手。我想出了以下,雖然這是站不住腳的,充其量:

const readonly = (target, key, descriptor) => Object.assign(descriptor, { writable: false }); 

class AngularComponent { 
    constructor() { 
    let ctorArgs = [...arguments]; 
    let argNames = ctorArgs.pop(); 

    // let's leave comprehensions out of this :) 
    this.deps = 
     argNames.reduce((result, arg, idx) => Object.assign(result, ({ [arg]: ctorArgs[idx] })), {}); 
    } 
} 

@angularInjectAnnotationFromCtor 
class MyClass extends AngularComponent { 
    constructor (one, two, three) { 
     super(one, two, three, MyClass.$inject); 
    } 
} 

呀,這是比我們更糟糕的開始...

所以,問題是屆時,任何人都可以提出一個更合理的解決方案這個?或者我們應該在未來的幾年內隨時隨地對Chrome中的Proxies有所期待?

回答

1

你想法的靜態部分基本上沒有$inject。沒有用。

我建議忘記的想法或傳遞參數給裝飾:

@inject('dep1', 'dep2', 'dep3') 
class MyClass { 
    constructor (dep1, dep2, dep3) { 
    /* app logic */ 
    } 
} 

構造的一部分可以用經典的裝飾圖案來完成:

function inject() { 
    var dependencies = [...arguments]; 

    return function decorator(target) { 
    target.$inject = dependencies; 

    return function() { 
     this.deps = {}; 
     dependencies.forEach((dep, index) => { 
     this.deps[dep] = arguments[index]; 
     }); 

     target.constructor.apply(arguments, this); 
     return this; 
    } 
    } 
} 
+0

很不錯的!雖然我不明白第一句話 - 爲什麼沒有意義?爲什麼沒有呢? –

+0

@IlyaAyzenshtok Angular可以從構造函數本身獲得依賴關係。明確定義的'$ inject'的要點是讓字符串不會因縮小而丟失。所以基本上你正在嘗試做Angular已經做的事情。 – zeroflagL

+0

關鍵是在沒有框架特定的明確儀式的情況下創建縮小安全的代碼。靜態的'''inject'''裝飾器可以做到這一點 - 生成可以安全縮小的代碼,並且可以處理Angular問題。但除此之外,很好的答案,謝謝!我不知何故錯過了類裝飾器也可以返回的事實。 –