2013-08-26 33 views
6

Aynı imzaya sahip iki/daha fazla hizmetim var. Direktife dinamik olarak enjekte edebilir miyim? , Yönlendirme hizmet/fabrikasına yönlendirme

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; 
     } 
    } 
}); 

altında gibi bir şey Sonra

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

altında aynı imza ile daha fazla hizmet ekleyerek olurdu olarak direktifini kullanmak mümkün olmalıdır ve ben değiştirmeden yönergesi kullanmak mümkün olmalıdır mümkün mü?

cevap

13

Bu şekilde mümkün değil.

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

ve sonra görünümünde: Nihayet

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

yapmanız gerekenler yapabileceğiniz en iyi hizmetin bir örneğini döndürür, üst kapsamı bir işleve direktif kapsamı ciltlemektir ebeveyn kapsamına getMyData() ve getYourData() ekleyin:

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

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

Plunker senaryoyu here.

Yine de başka bir yaklaşım düşünebilirim: soyut bir fabrika yaratabilir ve onu direktifin içine enjekte edebilir ve ardından yönerge için bir parametreyi geçirebilir, böylece doğru fabrikayı doğru hizmeti oluşturmak için anlatabilir. Böyle bir şey:

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; 
    } 
    } 
}); 

Ve şimdi yönergeye türünü geçmesi gerekiyor:

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

Plunker here.

+0

Her iki yaklaşım gerçekten iyi görünüyor. – Murali

+0

Veri toplama işlemini gerçekleştiren ve ng-controller = "YourCtrl" –

+0

'u kullanarak yönlendiriciye ileten basit bir denetleyici tanımlayabilirsiniz. Gerçekten yararlı. Teşekkürler! –

9

Bir ana denetleyiciye veya fabrika fabrikalarına gerek kalmadan bir çözüm.

yönergede, fabrika örneğini almak için $ enjektör hizmeti enjekte:

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

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

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

Bildirim o denetleyici yönteminde oluyor. Bağlantı işlevinde $ injector.get() çalışmasını yapamadım.

Şablon:

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

- Düzenleme - bağlantı fonksiyonu içinde

Çalışma çözeltisi:

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

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

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