2014-12-22 40 views
1

有多個angularJS指令相同的功能(使用chart.js之的角版本之一)多angularJS指令有我如何

現在我有一對夫婦的功能,我需要在這些指令使用。

什麼是讓我不再重複自己的好方法,所以從指令中刪除代碼並將它放在一個地方。由於該代碼無論如何都是相同的。 我已經研究了範圍的繼承,但還沒有能夠解決這個問題。

這是在多個指令使用的代碼:

 $scope.widgetData = false; 
     $scope.graphData = false; 
     $scope.graphSelectorIndex = 0; 

     $scope.graphSelector = [ 
      { 'byPeriod' : 'Periode'}, 
      { 'byHour' : 'Uur' }, 
      { 'byDay' : 'Dag'} 
     ]; 

     $scope.graphSelectorByText = function (text) { 
      switch (text) { 
       case ('byPeriod'): 
        $scope.selector = 'byPeriod' 
        $scope.graphData = $scope.allGraphData.byPeriod; 
        $scope.graphType = 'Line'; 
        break; 
       case ('byDay'): 
        $scope.selector = 'byDay' 
        $scope.graphData = $scope.allGraphData.byDay; 
        $scope.graphType = 'Line'; 
        break; 
       case ('byHour'): 
        $scope.selector = 'byHour' 
        $scope.graphData = $scope.allGraphData.byHour; 
        $scope.graphType = 'Bar'; 
        break; 
      } 
     } 

     $scope.graphSelectorByInt = function (int) { 
      switch (int) { 
       case (0): 
        $scope.selector = 'byPeriod'; 
        $scope.graphData = $scope.allGraphData.byPeriod; 
        $scope.graphType = 'Line'; 
        break; 
       case (1): 
        $scope.selector = 'byDay'; 
        $scope.graphData = $scope.allGraphData.byDay; 
        $scope.graphType = 'Line'; 
        break; 
       case (2): 
        $scope.selector = 'byHour'; 
        $scope.graphData = $scope.allGraphData.byHour; 
        $scope.graphType = 'Bar' 
        break; 
      } 
     } 

     $scope.graphSelectorPrev = function() { 
      $scope.graphSelectorIndex--; 
      if ($scope.graphSelectorIndex < 0) { 
       $scope.graphSelectorIndex = $scope.graphSelector.length-1; 
      } 
      $scope.graphSelectorByInt($scope.graphSelectorIndex); 
      console.log($scope.graphSelectorIndex); 

     } 

     $scope.graphSelectorNext = function() { 
      $scope.graphSelectorIndex++; 
      if ($scope.graphSelectorIndex >= $scope.graphSelector.length) { 
       $scope.graphSelectorIndex = 0; 
      } 
      $scope.graphSelectorByInt($scope.graphSelectorIndex); 
      console.log($scope.graphSelectorIndex); 
     } 

一些HTML代碼:

<div class="controls"> 
     <span class="btn_arrow previous inactive" ng-click="graphSelectorPrev()">Vorige</span> 
     <p>{+ selector +}</p> 
     <span class="btn_arrow next" ng-click="graphSelectorNext()">Volgende</span> 
    </div> 

由於任何人,可以幫助!

+0

也許我不說得對,但唯一的出版物是案例結構中的東西? – semptic

+0

你應該使用對象:其中一個有像'byPeriod'等鍵作爲值的函數。當你需要'int'查找函數時,你應該這樣做'var key = Object.keys(object)[int]; object(key);' –

+0

@semptic我列出的函數在多個指令中使用,所以我怎麼把它放到一箇中心位置。 – Maxicus

回答

0

我個人喜歡服務方式。

參見:http://jsfiddle.net/elennaro/b48jex3w/33/

下面是代碼:

HTML

<div ng-controller="BaseCtrl"> 
<div class="controlls"> <span class="btn_arrow previous inactive" ng-click="graphSelectorInc(-1)">Vorige</span> 

    <p>{{ selector }}</p> <span class="btn_arrow next" ng-click="graphSelectorInc(+1)">Volgende</span> 

</div> 

JS

angular.module('myApp', []) 
.service('GraphSelector', function() { 
var graphSelectorIndex = 0; 
var graphSelector = [{ 
    'byPeriod': 'Periode' 
}, { 
    'byHour': 'Uur' 
}, { 
    'byDay': 'Dag' 
}]; 
return { 
    selector: this.selector, 
    inc: function (inc) { 
     graphSelectorIndex += inc; 
     if (graphSelectorIndex < 0) { 
      graphSelectorIndex = graphSelector.length - 1; 
     } else if (graphSelectorIndex >= graphSelector.length) { 
      graphSelectorIndex = 0; 
     } 
     console.log(Object.keys(graphSelector[graphSelectorIndex])); 
     return graphSelector[graphSelectorIndex][Object.keys(graphSelector[graphSelectorIndex])[0]]; 
    } 

} 
}).controller('BaseCtrl', function ($scope, GraphSelector) { 

$scope.graphSelectorInc = function (inc) { 
    $scope.selector = GraphSelector.inc(inc); 

}}); 

你看,我有一個服務圖這是一個單身人士,它存儲graphSelectorIndex和graphSelector對所有控制器/指令都是相同的,任何人都會打電話給他。

因此,您可以從任何想要切換當前選擇器屬性的位置調用此服務。

我使用Object.keys來獲得返回到我們的控制器的當前選擇器狀態的值。但是如果你想要的話,你可以返回整個對象並獲取控制器中的值。

Angular JS服務是一個強大的工具,可以獲得DRY乾淨可讀的代碼,我也經常用它來在控制器之間共享一些數據。

+0

我真的很喜歡這個。我相信我會回頭看這段代碼以供參考,非常感謝! =) – Maxicus

1

首先,在這種情況下,你可以做一些幹這種方式:

HTML:

<div class="controlls"> <span class="btn_arrow previous inactive" ng-click="graphSelectorInc(-1)">Vorige</span> 

    <p>{{ selector }}</p> <span class="btn_arrow next" ng-click="graphSelectorInc(+1)">Volgende</span> 

</div> 

JS:

//Warning this approach is so called not monomorh(polymorph): the parameter of function is not strictly typed, so it lacks browser optimizations but in this case its not so important because code won't run often 
$scope.graphSelectorByAny = function (step) { 
    switch (step) { 
     case ('byPeriod'): 
     case (0): 
      $scope.selector = 'byPeriod' 
      $scope.graphData = $scope.allGraphData.byPeriod; 
      $scope.graphType = 'Line'; 
      break; 
     case ('byDay'): 
     case (1): 
      $scope.selector = 'byDay' 
      $scope.graphData = $scope.allGraphData.byDay; 
      $scope.graphType = 'Line'; 
      break; 
     case ('byHour'): 
     case (2): 
      $scope.selector = 'byHour' 
      $scope.graphData = $scope.allGraphData.byHour; 
      $scope.graphType = 'Bar'; 
      break; 
    } 
} 

$scope.graphSelectorInc = function (inc) { 
    $scope.graphSelectorIndex += inc; 
    if ($scope.graphSelectorIndex < 0) { 
     $scope.graphSelectorIndex = $scope.graphSelector.length - 1; 
    } else if ($scope.graphSelectorIndex >= $scope.graphSelector.length) { 
     $scope.graphSelectorIndex = 0; 
    } 
    $scope.graphSelectorByAny($scope.graphSelectorIndex); 
    console.log($scope.graphSelectorIndex); 

} 

我已爲你JSFiddle

但是它也有好處,有一個單獨的直接,我不能寫的原因,我不知道你想要在控制器中想要什麼數據。喲可以閱讀關於指令和數據綁定from the official docs

還可以考慮使用services您希望乘法控制器/指令執行相同的操作。

希望它能幫助你。

+0

剛剛測試過你的代碼,這已經好很多了,謝謝!我正在考慮在代碼中有一個指令是。 – Maxicus

0

不知道指令之間的確切區別(也許你甚至不需要多個指令)我會建議使用一個服務或者簡單地創建一個控制器並將其添加到指令模板中。

我只會去服務,如果你得到一些好處,在指令之間共享狀態,否則我會去控制器。

下面是一個簡單的例子就是我所說的「使用控制器」(上jsfiddle測試)的意思是:

angular.module('myApp', []) 
.controller('sharedCtrl', function() { 
    var self = this; 

    // $scope.doIt = ... 
    self.doIt = function (msg) { 
     alert(msg); 
    }; 
}) 
.directive('dir1', function() { 
    return { 
     restrict: 'E', 
     template: '<div ng-controller="sharedCtrl as ctrl"><button ng-click="ctrl.doIt(msg)">dir1</button></div>', 
     scope: {}, 
     link: function (scope) { 
      scope.msg = 'Hi, I\'m dir1!'; 
     } 
    }; 
}) 
.directive('dir2', function() { 
    return { 
     restrict: 'E', 
     template: '<div ng-controller="sharedCtrl as ctrl"><button ng-click="ctrl.doIt(msg)">dir2</button></div>', 
     scope: {}, 
     link: function (scope) { 
      scope.msg = 'Hi, I\'m dir2!'; 
     } 
    }; 
}); 

如果您需要從該指令範圍傳遞的東西,你可以簡單地將它傳遞給控制器​​的功能。

P.S .:我更喜歡controller as語法,而不是使用$scope。如果您不熟悉它,您可以使用$scope替換self,但我建議進一步查看controller as

0

您可以創建一個包含可重用邏輯的共享控制器,然後將其動態鏈接到您的指令。

所以,你的控制器將是:

app.controller('sharedCtrl', function($scope) { 
    $scope.widgetData = false; 
    $scope.graphData = false; 
    $scope.graphSelectorIndex = 0; 

    $scope.graphSelector = [ 
     { 'byPeriod' : 'Periode'}, 
     { 'byHour' : 'Uur' }, 
     { 'byDay' : 'Dag'} 
    ]; 

    $scope.graphSelectorByText = function (text) { 
     switch (text) { 
      case ('byPeriod'): 
       $scope.selector = 'byPeriod' 
       $scope.graphData = $scope.allGraphData.byPeriod; 
       $scope.graphType = 'Line'; 
       break; 
      case ('byDay'): 
       $scope.selector = 'byDay' 
       $scope.graphData = $scope.allGraphData.byDay; 
       $scope.graphType = 'Line'; 
       break; 
      case ('byHour'): 
       $scope.selector = 'byHour' 
       $scope.graphData = $scope.allGraphData.byHour; 
       $scope.graphType = 'Bar'; 
       break; 
     } 
    } 

    $scope.graphSelectorByInt = function (int) { 
     switch (int) { 
      case (0): 
       $scope.selector = 'byPeriod'; 
       $scope.graphData = $scope.allGraphData.byPeriod; 
       $scope.graphType = 'Line'; 
       break; 
      case (1): 
       $scope.selector = 'byDay'; 
       $scope.graphData = $scope.allGraphData.byDay; 
       $scope.graphType = 'Line'; 
       break; 
      case (2): 
       $scope.selector = 'byHour'; 
       $scope.graphData = $scope.allGraphData.byHour; 
       $scope.graphType = 'Bar' 
       break; 
     } 
    } 

    $scope.graphSelectorPrev = function() { 
     $scope.graphSelectorIndex--; 
     if ($scope.graphSelectorIndex < 0) { 
      $scope.graphSelectorIndex = $scope.graphSelector.length-1; 
     } 
     $scope.graphSelectorByInt($scope.graphSelectorIndex); 
     console.log($scope.graphSelectorIndex); 

    } 

    $scope.graphSelectorNext = function() { 
     $scope.graphSelectorIndex++; 
     if ($scope.graphSelectorIndex >= $scope.graphSelector.length) { 
      $scope.graphSelectorIndex = 0; 
     } 
     $scope.graphSelectorByInt($scope.graphSelectorIndex); 
     console.log($scope.graphSelectorIndex); 
    } 

}); 

而且你的指令是這樣的:

app.directive('myDirective', function() { 
    return { 
     restrict: 'E', 
     controller: '@', 
     name: 'myDirectiveCtrl', 
     link: function($scope, $element, $attrs) { 
      // add directive specific logic 
     } 
    } 
}); 

則加價幅度是這樣的:

<my-directive my-directive-ctrl="sharedCtrl"></my-directive>