2014-12-22 3 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); 

}}); 

Вы видите, что есть служба GRAPHS избиратель, который является singleton, и он хранит graphSelectorIndex и graphSelector одинаково для всех контроллеров/директив, кто его вызовет.

Таким образом, вы можете позвонить в эту службу из любого места, где вы хотите переключить текущие свойства селектора.

Я использую Object.keys, чтобы получить только значение текущего состояния выбора, которое возвращается на наш контроллер. Но если вы хотите, вы можете вернуть весь объект и получить значение в контроллере.

Угловые услуги JS - это мощный инструмент для получения СУХОГО чистого и читаемого кода, а также часто использую его для обмена некоторыми данными между контроллерами.

+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 для вас.

Но это также хорошо иметь отдельный указатель, я не могу написать причину, по которой я не знаю, какие данные вы действительно хотите быть в контроллере. Yo может читать о директивах и привязке данных from the official docs.

Также рассмотрите возможность использования services whem вы хотите, чтобы контроллеры/директивы умножения выполнялись одинаково.

Надеюсь, это поможет вам.

+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. Если вы не знакомы с ним, вы можете заменить self на $scope, но я предлагаю посмотреть дальше в 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> 
Смежные вопросы