2013-08-26 10 views
6

同じシグネチャを持つ2つ以上のサービスがあります。この指令に動的に注入することはできますか?ディレクティブへのサービス/工場の投入

var app = angular.module('app',[]); 
app.factory('myData', function(){ 
    return { 
     name : "myName", 
     id : 1, 
     create: function(){ 
      //do something 
     } 
    } 
}); 
app.factory('yourData', function(){ 
    return { 
     name : "yourName", 
     id : 1, 
     create: function(){ 
      //do something 
     } 
    } 
}); 
app.directive('changeIt',function($compile){ 
    return { 
     restrict: 'CA', 
     scope:{ 
      data : '=' //or some oether syntax? 
     }, 
     link: function (scope, element, attrs) { 
      scope.name = data.name; 
     } 
    } 
}); 

以下のようなものその後、私は、私は同じシグネチャを持つより多くのサービスを追加されるだろうと私は変更せずにディレクティブを使用することができるはず

<div class='change-it' data='myData'>{{name}}</div> 
<div class='change-it' data='yourData'>{{name}}</div> 

以下のようにディレクティブを使用することができるはずです、出来ますか?

答えて

13

これは不可能です。

app.directive('changeIt', function(){ 
    return { 
    restrict: 'CA', 
    scope: { getDataFn : '&' }, 
    link: function (scope) { 
     scope.name = getDataFn().name; 
    } 
    } 
});  

、その後、あなたのビューで:最後に

<div class='change-it' get-data-fn='getMyData()'></div> 
<div class='change-it' get-data-fn='getYourData()'></div> 

、必要にあなたができる最善のは、あなたのサービスのインスタンスを返し、親スコープの機能にディレクティブのスコープをバインドしています親スコープにgetMyData()getYourData()を追加します。

app.controller('Ctrl', function($scope, myData, yourData) { 
    $scope.getMyData = function() { 
    return myData; 
    }; 

    $scope.getYourData = function() { 
    return yourData; 
    }; 
}); 

Plunkerスクリプトhere

抽象的なファクトリを作成してディレクティブに挿入し、そのディレクティブにパラメータを渡して、抽象的なファクトリに正しいサービスを作成するよう指示することもできます。このような何か:

app.service('dataFactory', function(myData, yourData) { 
    this.create = function(type) { 
    if (type === 'myData') 
     return myData; 
    else if (type === 'yourData') 
     return yourData; 
    }; 
}); 

app.directive('changeIt', function(dataFactory){ 
    return { 
    restrict: 'CA', 
    scope: true , 
    link: function (scope, element, attrs) { 
     scope.name = dataFactory.create(attrs.type).name; 
    } 
    } 
}); 

そして今、あなたはディレクティブに型を渡す必要があります。

<div class='change-it' type="myData"></div> 
<div class='change-it' type="yourData"></div> 

Plunker here

+0

は、両方のアプローチが本当に良く見えます。 – Murali

+0

私はあなたがdatacallを実行し、ng-controller = "YourCtrl"を使ってディレクティブに渡す単純なコントローラを定義できると思います。 –

+0

本当に役に立ちました。ありがとう! –

9

ここでは、親コントローラまたは工場の工場を必要としないソリューションです。ディレクティブで

、工場出荷時のインスタンスを取得するために$インジェクタサービスを挿入:

app.directive('changeIt',function(){ 
     return { 
      scope:{ 
       factoryName : '@' 
      }, 
      controller: function ($scope, $injector) { 

       var factoryInstance = $injector.get($scope.factoryName); 

       $scope.name = factoryInstance.name; 
      } 
     } 
    }); 

は、コントローラのメソッドで起こって注意してください。リンク関数で$ injector.get()を動作させることができませんでした。

テンプレート:

<div class='change-it' factory-name="myData"> {{ name }} </div> 
<div class='change-it' factory-name="yourData"> {{ name }} </div> 

- 編集 - リンク関数内

作業溶液:

app.directive('changeIt',function(){ 
      return { 
       scope:{ 
        factoryName : '@' 
       }, 
       link: function (scope, element) { 

        var factoryInstance = element.injector().get(scope.factoryName); 

        scope.name = factoryInstance.name; 
       } 
      } 
     });