2013-05-08 3 views
4

Это для приложения AngularJS. У меня есть настраиваемая директива, которая зависит от службы.AngularJS: Когда действие пользователя воздействует как на модель, так и на DOM

Что мне действительно интересно, так это «угловой способ», связанный с действием пользователя, которое влияет как на модель, так и на DOM. Некоторые примеры кода:

HTML:

<form foo-places> 
    <!--other stuff --> 
    <span ng-repeat="place in places"> 
     <button ng-click="removePlace(place)">remove {{place}}</button> 
    </span>   
</form> 

JS:

angular.module('foo.directives', []).directive('fooPlaces', 
function(placesService) { 
    return { 
     controller : function($scope) { 
      $scope.places = placesService.places; 
        $scope.removePlace = function(name) { 
       placesService.removePlace(name); 
      }; 
      $scope.$on('placesChanged', function() { 
       $scope.places = placesService.places; 
      }); 
     }, 
     link : function($scope, element, attrs) { 
       //code to do stuff when user removes a place 
     } 
    } 
}) 

Когда пользователь удаляет место (нажав кнопку), мне также нужно делать вещи, чтобы возиться с DOM , например, прокрутите окно до вершины и т. д. Чувствуется странным наличие функции в контроллере, которая имеет дело с моделью, а затем еще одна функция в директиве, которая делает материал DOM ... но оба основаны на одном и том же пользователе действие.

Я передумал это или действительно что-то пропустил? Как я должен обрабатывать одно действие пользователя, которое касается как модели, так и DOM?

+0

У вас может быть отдельная директива, касающаяся изменений пользовательского интерфейса, которая использует 'scope. $ Watch' в вашей коллекции мест. Таким образом, вы можете обновить UI повсеместно для любых изменений в этой коллекции и просто добавить эту директиву в элемент разметки, соответствующий области, в которой вы работаете. Я сделал это в обоих направлениях, и я думаю, что добавление часов более чистое, чем смешивание изменения модели с помощью jQuery или других манипуляций с dom манипуляциями в функции ссылок. – Sounten

+0

@Sounten - Я не знаю, согласен ли я с тем, что добавление $ watch, как вы предложили, является более чистым. Но я знаю, что то, что я думаю об угловых за пределами основных примеров, не всегда соответствует лучшему способу делать реальные вещи! Спасибо за ввод. Я буду играть с этим. – BjornJohnson

ответ

4

Когда вы имеете дело с AngularJS, возможно, вы слышали фразу «Модель - единственный источник истины». Если вы поймете эту часть, то остальная часть вещей легко встанет на свои места. Это «Угловой путь».

Когда пользователь взаимодействует - он не взаимодействует с DOM или представлением. Он взаимодействует с моделью. Само представление - это просто «вид» модели. Могут существовать другие взгляды на одну и ту же модель, поэтому модель является единственным источником истины. Теперь, какой угловой позволяет вам делать, это вносить изменения в модель, когда пользователь взаимодействует. Вы вносите эти изменения и потому, что модель изменилась, начало представления отражает изменение состояния модели.

Также, чтобы подчеркнуть разделение проблем - директива должна редко обращаться непосредственно к службе. Директива - это часть DOM, что означает, что это фрагмент представления. Служба обычно имеет какое-то отношение к бизнес-логике или представляет собой модель. В MVC или MVVM вы не можете напрямую взаимодействовать с моделью. Вы всегда используете ViewModel или Controller между ними. Это позволяет свести к минимуму зависимости.

Ваш ScrollToTop может быть услугой, которую вы вызываете у своего контроллера (см. , который является сервисом в Угловом). Он не делает то, что вы хотите, но его прокручивающийся сервис, который вам также нужно реализовать.

EDIT:

Чтобы уточнить, вы не обычно делают DOM manipulately материал в сфере услуг. Сценарий, в котором вы могли бы рассмотреть материал DOM-манипулирования в службе, - это когда, то, что вы пытаетесь сделать, не принадлежит к какому-либо определенному элементу html, а что-то, что должно произойти на вашем уровне приложения.

Позвольте мне объяснить это. Например, если вы пытаетесь сделать что-то вроде диалогового/модального окна - в angularJS вы бы подумали, что идеальным местом для чего-то подобного является директива, так как это общий компонент пользовательского интерфейса. Но если вы думаете об этом, директива в AngularJS связана с элементом. Вы всегда ассоциируете директиву с элементом html. Но, как мы видели, диалог - это не то, что вы присоединяете к элементу, а скорее нечто глобальное по своей природе. Вероятно, это исключение.

То же самое относится и к некоторым $window и $document связанным вещам (например, прокруткам).Они не принадлежат к какому-либо определенному элементу (если вы хотите прокручивать внутри div, это должна быть директива), следовательно, они должны быть сервисом. Кроме того, это сервис, который вы, вероятно, можете ввести в директиву. Скажем, каждый раз, когда вы запускаете свою директиву, вы хотите прокручиватьToTop или открывать диалог. Вы можете вводить эти виды услуг в свои директивы. Такими услугами, которые вы, вероятно, не должны вводить в директиву, являются сервисы, связанные с бизнес-логикой. Рассматривайте директиву в качестве повторно используемого компонента пользовательского интерфейса.

Конечно, вы можете создать компонент более высокого уровня (материал, который вы пытаетесь), который создает DSL, но тогда вам нужно точно знать, что вы делаете. До тех пор я предлагаю вам придерживаться простого старого контроллера, директивы и услуг, и каждый из них управляет своими собственными проблемами.

+0

Спасибо. Я думаю, что вы проделали хорошую работу, прояснив для меня разделение проблем - особенно с вашим заявлением: «директива должна редко обращаться непосредственно к службе». У меня есть несколько последующих вопросов. Что, если я хотел бы делать другие вещи, которые «DOM-манипулирование-иш», кроме прокрутки вверх? Предлагаете ли вы предлагать услуги для каждого из этих потенциальных вещей? Как вы можете себе представить, многие мои вопросы вызваны «Только манипулирование DOM в директиве». Нарушает ли это дела, связанные с DOM в службе? Или я тоже неправильно понимаю услуги? :) – BjornJohnson

+0

Отличные разъяснения и объяснения, связанные с приложениями/глобальными материалами, которые просто не соответствуют директивам, а также предложение не вводить услуги, которые касаются бизнес-логики, но позволять это при работе с такими вещами, как диалоги или doc- уровень прокрутки. Спасибо. – BjornJohnson