2015-04-09 2 views
3

Я недавно унаследовал угловой модуль, написанный сторонним разработчиком. Я никогда раньше не работал с угловатыми, и мне было предложено внести некоторые довольно существенные изменения, но я борюсь с несколькими проблемами (я обещаю, что в конце есть вопрос).AngularJS - Некоторые вопросы о новинках в области производительности и масштаба

По сути, модуль представляет собой вопросник с несколькими вариантами выбора, с помощью кнопки и щелчком мыши, чтобы выбрать ответ, и кнопку «вперед/назад» для перемещения между вопросами.

На данный момент модуль жестко закодированным использовать 5 кнопок, и положение кнопок устанавливаются в контроллере в виде так:

// scope here is the scope for the main controller 
$scope.answerOptions = [ 
    { pos: 70 }, 
    { pos: 215 }, 
    { pos: 360 }, 
    { pos: 505 }, 
    { pos: 650 } 
]; 

позы просто левое смещение и вертикальное положение исправлено. это реализуется на шаблоне так:

<div class="circle" ng-repeat="o in answerOptions" 
    option-pos="{{o.pos}}" 
    ng-hide="sectionEnd" 
    ng-class="selectedOptionStyle($parent.selectedAnswer - 1 == $index)" 
    ng-click="selectAnswer($index)"> 
</div> 

И директива optionPos тогда:

.directive('optionPos', function(){ 
    return function(scope, elm, attrs) { 
    attrs.$observe('optionPos', function(x){ 
     elm.css('left', x - 60 + 'px'); 
    }) 
    } 
}) 

Меня попросили, чтобы заставить его работать с любым количеством кнопок и позиционирования в обоих х и у , и разрешить настраиваемые ответы (на данный момент он просто отправляет индекс массива нажатой кнопки обратно на сервер). Я думал, что это будет легкое изменение, и, по общему признанию, было бы достаточно легко, если бы я реализовал ту же систему, установив x и y, используя интерполяцию, а затем просто добавив Y в директиву optionPos. Однако у меня есть пара проблем с таким подходом:

  • Он не очень хорошо масштабируется для количества атрибутов на кнопке. например а также x и y есть некоторые другие данные, которые я бы хотел назначить кнопке из объекта responseOption (например, ответ на отправку на сервер и, возможно, другие вещи в будущем), и я не хочу должны назначать каждый из них как отдельный атрибут элемента DOM.
  • Я обеспокоен тем, что attrs.$observe излишне ресурсоемкий, поскольку значение никогда не изменится после загрузки модуля, а $ observ (предположительно?) Добавит часы к этому свойству. Аналогично, для использования интерполяции для установки координат в элементе DOM.
  • В некотором неопределимом смысле это кажется неправильным, так как есть, вероятно, лучший способ сделать это, я просто не задаю правильным вопросам Google.

То, что я пытался сделать, после того, как много чтения документации и руководств ANGULAR является чем-то вроде этого:

// this would no longer be hard coded into the controller 
// but once it is retrieved, this is what is set in the scope 
// scope is still the main controller scope 
$scope.answerOptions = [ 
    { Answer: 1, pos: { X: 180, Y: 120} }, 
    { Answer: 2, pos: { X: 360, Y: 120} }, 
    { Answer: 3, pos: { X: 540, Y: 120} } 
]; 

шаблона:

<div class="circle" ng-repeat="o in answerOptions" 
    answer-option="o" 
    option-button 
    ng-hide="sectionEnd" 
    ng-class="selectedOptionStyle($parent.selectedAnswer - 1 == $index)" 
    ng-click="selectAnswer(o.Answer)"> 
</div> 

директива:

.directive('optionButton', function(){ 
    return { 
     restrict: 'A', 
     scope: { 
      answerOption: '=' 
     }, 
     link: function(scope, elm, attrs) { 
      elm.css('left', scope.answerOption.pos.X - 60 + 'px'); 
      elm.css('top', scope.answerOption.pos.Y - 60 + 'px'); 
     } 
    } 

Проблема с вышеприведенным решением - моя директива создавая изолированную область видимости, поэтому все остальные директивы с вызовами функций в области, такие как ng-hide, теперь разбиты, и я не хочу перепроектировать весь модуль для того, что по сути является очень простым изменением.

И так, как и было обещано после моего долгого бессвязного вопроса: вопрос:

Кому-то, у кого больше, чем у моего 24-часового опыта работы с угловыми, я об этом не так? Проблемы, которые я испытал, которые привели меня к этому моменту, выглядят как запах кода, но я не уверен, что его, потому что оригинальный разработчик написал модуль таким образом, который трудно поддерживать/расширять, или если я беру полностью неправильный подход. Проблемы, с которыми я столкнулся, по-видимому, связаны с тем, что по существу вся логика приложения настраивается как различные функции в объеме основного контроллера. Для настройки области для этого контроллера требуется около 800 строк JS, причем многие функции определяют целый ряд разных вещей. Это способ создания углового приложения с большей частью логики в области видимости, а затем вызов его непосредственно из шаблона, например. ng-hide="sectionEnd"?

+2

800 строк JS для кода настройки контроллера не является нормальным. Мое совершенно не экспертное мнение, загляните в документы еще пару дней, и вы перепишете это через пару часов, чтобы быть тем, что вам нужно, и многое другое. Кроме того, трудно судить о вашем подходе без подробных требований. – user2847643

ответ

1

Один контролер монстра не является хорошей практикой. Каждый контроллер на странице должен быть сфокусирован и должен иметь не более 5 методов (руководство). Сфокусировав контроллеры, вы управляете тем, как вы получаете свое приложение, получает свои данные.

Как только у вас есть контроллеры для извлечения данных вашего приложения, вы должны использовать директивы для инкапсуляции функциональности в директивы многократного использования.

Кроме того, $ observ не будет нести значительную стоимость, если атрибут и его интерполированное значение никогда не изменятся.

Я рекомендую следующие рекомендации:

  1. Реализовать услуги для извлечения данных приложения
  2. Контроллеры должны вызвать службы для извлечения данных приложений и прикрепить его к области.
  3. Директивы должны помочь поддерживать тонкий контроллер и улучшать ремонтопригодность, сохраняя сложную или общую логику в повторно используемых директивах.
+1

Re 3, я вижу директивы как способ инкапсуляции логики представления. Они должны помочь поддерживать тонкие контроллеры, но это не их конкретная цель. –

+0

Да, это побочный эффект, но он говорит о ремонтопригодности - это действительная точка – pixelbits

+0

@DrewR Это подтверждает то, что я видел с других сайтов. Это [руководство по службам, контроллерам и директивам] (http: // kirkbushell.я/когда-к-использованию-директоры-контроллеры-или-услуги-в-угловом) сделал аналогичную точку (и был очень полезен для меня, если кто-то еще сталкивается с этим через google и хотел бы, чтобы руководство для начинающих о том, когда использовать службы , контроллеры и директивы) – Anduril

Смежные вопросы