2016-10-03 10 views
0

私は、基本クラス(活字体)に(アンギュラ材質から)$ mdToastの単一のインスタンスを置くことについての具体的な質問があります。 UIに5つのタブがあり、それぞれに別々のコントローラーインスタンス(つまり、注入とctorの宣言を分けて)を与えました。 $ mdToast宣言をどこにでも別々に宣言するのではなく、基本クラスに移動するのが理にかなっていました。基底クラスは独自の "$ inject"を持っていますが、それは派生クラスのものに取って代わられているようです。私は$ mdToastを共通の基底クラスに移動する最もクリーンな方法を見つけようとしています。最善の方法は何ですか?ここで私のコードはどのように見えるです。元$ mdToastラインがコメントアウトされて単一インスタンス/注入

注:以下の基底クラスと

export class MainController extends BaseController { 
static $inject = [ 
    'tableService', 
    '$mdSidenav', 
    //'$mdToast', 
    '$mdDialog', 
    '$mdMedia', 
    '$mdBottomSheet']; 

constructor(
    private tableService: ITableService, 
    private $mdSidenav: angular.material.ISidenavService, 
    //private $mdToast: angular.material.IToastService, 
    private $mdDialog: angular.material.IDialogService, 
    private $mdMedia: angular.material.IMedia, 
    private $mdBottomSheet: angular.material.IBottomSheetService) { 
    super(); 
    var self = this; 
}} 

。 $ mdToastの注入と$ mdToastの宣言がコンストラクタの外側にあることに注意してください。

export class BaseController { 
static $inject = [ 
    '$mdToast']; 

constructor(
) { 
    var self = this; 
} 

private $mdToast: angular.material.IToastService; 

openToast(message: string): void { 
    this.$mdToast.show(
    this.$mdToast.simple() 
     .textContent(message) 
     .position('top right') 
     .hideDelay(3000) 
); 
}} 

私はSOのどこか別のところで$ injectorを賢明に使用していましたが、それは私のためには機能しませんでした。すべての反応がうれしく受け取りました!

答えて

2

これは、このようなパターンであってもよい:

export class BaseController { 
    static $inject = [...]; 
    ... 
} 

export class MainController extends BaseController { 
    static $inject = [...BaseController.$inject, 
     ... 
    ]; 

    constructor(...deps) { 
     const superDeps = BaseController.$inject.map((dep, i) => deps[i]); 

     super(...superDeps); 

     const thisDeps = deps.slice(superDeps.length); 
     const thisDepNames = this.constructor.$inject.slice(superDeps.length); 
     ... 


    } 

    ... 
} 

それはそれは一度か二度以上使用された場合に利便性のための注射剤やデコレータのためのいくつかの基底クラスに詰め、それはパースについて常にすることができます2つの配列$injectおよびdepsを使用して、thisに依存関係を割り当てます。

この方法は、タイプセーフではありません。

活字体にとっては、WETが、タイプセーフなものを維持することが好ましいです。我々は常に一貫性を保つために最初に来た親クラスの依存関係を持ちたい:

export class BaseController { 
    static $inject = ['$mdToast']; 

    constructor(protected $mdToast: angular.material.IToastService) { ... } 
} 

export class MainController extends BaseController { 
    static $inject = [ 
     '$mdToast' 

     'tableService', 
     ... 
    ]; 

    constructor(
     $mdToast: angular.material.IToastService, 

     private tableService: ITableService, 
     ... 
    ) { 
     super($mdToast); 
    }} 
    ... 
} 
+0

あなたの声明に興味深い知恵。あなたは私に多くのことを考えさせました。 2番目の例では、まだ回避しようとしていた$ mdToastを2回注入する必要があります。 BaseControllerを継承しているすべてのクラスで、$ mdToastのインスタンスを1つしか取得できないようにするにはどうすればよいですか? (btw、i upvoted) –

+0

Dupe '$ mdToast'はここに正しいです。とにかくインジェクタによるコンストラクタ引数として渡されます(これはクラスデコレータで修正できますが、正直言ってそれは価値がありません)。しかし、これは 'this'に1度だけ割り当てられ、可視性をオーバーライドできません(親クラスのコンストラクタで' protected $ mdToast'があり、子クラスのコンストラクタでは '$ mdToast'のみです)。もちろん、 '$ mdToast'はコントローラインスタンスごとに1回だけ注入されます。クラスが継承されているかどうかは関係ありません。継承がどのように動作するかです。 – estus

+0

週末やハリケーン・マシューからのすべての難民の間、私はあなたの変更を実行することに決めました。彼らは約束どおりに働きます。私はまだWETする必要があるのが嫌いですが、それについてのあなたのコメントは、TypeScriptのタイプセーフを私に響かせておくための最良の方法です。私はハードコアのC++/Java/C#のバックグラウンドから来て、Javascript/TypeScriptでこのように考えてみると、過去に比べてより柔軟にする必要がある良い場所です。 –

1

この方法は、確かに、ハックですが、それは仕事を得るでしょう、かなりドライな方法です。 ES6のインポート/エクスポートステートメントを利用して、必要な場所でこのサービスを利用できるようにします。

export let $injector; 

class injectorConfig { 
    static $inject = ['$injector']; 
    constructor (private $originalInjector) { 
     $injector = $originalInjector; 
    } 
} 

app.config(injectorConfig); 

その後、あなたのBaseController.tsファイルがこの

import {$injector} from '../yourfilename'; 

export class BaseController { 
    private $mdToast = $injector.get('$mdToast'); 
    constructor() { 
     var self = this; 
    } 
} 

ようになり、それが動作するという理由だけで、あなたがそれに傾く必要がありますという意味ではありませんが、このような状況で、私はこの手法は理にかなっていると思います。 Angularがこのconfigブロックを実行するまで$ injectorは利用できないので、configブロックが実行される前に実行されるプロバイダやその他のコードでは使用できません。

+0

これは、$ mdToastのシングルトン値を保証するきれいな方法のようです。ありがとう! –

関連する問題