2013-10-28 2 views
0

Попытка найти лучшие практики с помощью AngularJS. Вот сделка:AngularJS - как делиться функциональностью между контроллерами

Существуют две разные страницы с формами, каждая из которых имеет свои собственные поля формы. Но в обеих формах существует одна общая функциональность: у них есть поле автозаполнения, которое пользователь может использовать для выбора нескольких адресов электронной почты, существующих в системе.

Выбранные адреса электронной почты хранятся в модели/области, чтобы они могли отображаться на странице HTML. Вот пример:

<div ng-controller="MyCtrl"> 
    <form ng-submit="selectCurrentEmail()" novalidate> 
     <input type="text" 
       class="form-control" 
       ng-model="responsiblePerson" /> 
     <input type="submit" value="Add" /> 

     <div ng-repeat="email in formData.selectedEmails"> 
      <div> 
       {{email}} <a href="" ng-click="removeEmail(email)">x</a> 
      </div> 
     </div> 
    </form> 
</div> 

и angularjs часть:

var myApp = angular.module('myApp', []); 

function MyCtrl($scope) { 
    $scope.formData = {selectedEmails: []}; 

    $scope.selectEmail = function(email) { 
     if (email != null && $.inArray(email, $scope.formData.selectedEmails) == -1) { 
      $scope.formData.selectedEmails.push(email); 
      $scope.responsiblePerson = null; 
     } 
    }; 

    $scope.removeEmail = function(email) { 
     var index = $.inArray(email, $scope.formData.selectedEmails); 

     if (index != -1) { 
      $scope.formData.selectedEmails.splice(index, 1); 
     } 
    }; 

    $scope.selectCurrentEmail = function() { 
     $scope.selectEmail($scope.responsiblePerson); 
    }; 
} 

http://jsfiddle.net/PqpYj/

(не содержит автозаполнения, так как это не главный вопрос здесь ..)

Это все работает нормально, но я не хочу повторять одну и ту же логику в обоих контроллерах. Я хотел бы иметь сервис или базовый контроллер, который может позаботиться о настройке и удалении выбранных адресов электронной почты. И когда пользователь будет выполнен, область будет иметь только выбранные адреса электронной почты.

Итак, как вы думаете, есть ли хороший способ обобщить три функции в области? Любые идеи делают это лучше?

+1

Как вы предположили, напишите директивный модуль для вашего поля автозаполнения, который сохраняет угловое обслуживание – Sprottenwels

+0

Возможный дубликат [Может ли один контроллер вызвать другой в AngularJS?] (Http://stackoverflow.com/questions/9293423/can -one-controller-call-another-in-angleularjs) – Stewie

+0

Использование услуг - лучший вариант здесь – BKM

ответ

1

Поскольку это элемент интерфейса, я бы поставил логику в Директиву.

myApp.directive('mailSelector', function() { 
    return { 
     scope: { 
      emails: '=' 
     }, 
     template: '<form ng-submit="selectCurrentEmail()" novalidate>' + 
     '<input type="text"'+ 
     '  class="form-control"'+ 
     '  ng-model="responsiblePerson" />'+ 
     '<input type="submit" value="Add" ng-click="selectCurrentEmail()" />'+ 

     '<div ng-repeat="email in emails">'+ 
     ' <div>' + 
     '  {{email}} <a href="" ng-click="removeEmail(email)">x</a>' + 
     ' </div>' + 
     '</div>' + 
    '</form>',   
     link: function($scope, $element, $attrs) { 
      $scope.selectCurrentEmail = function() { 
       $scope.selectEmail($scope.responsiblePerson); 
      } 

      $scope.selectEmail = function(email) { 
       if (email != null && $.inArray(email, $scope.emails) == -1) { 
        $scope.emails.push(email); 
        $scope.responsiblePerson = null; 
       } 
      } 

      $scope.removeEmail = function(email) { 
       var index = $.inArray(email, $scope.emails); 
       if (index != -1) { 
        $scope.emails.splice(index, 1); 
       } 
      }; 
     } 
    }; 
}); 

Контроллеры могут получить список писем от директивы по emails параметра, определенного с помощью директивы.

Я создал JSFiddle here.

Чтобы поделиться ранее введенными адресами электронной почты для автозавершения, я бы изменил директиву на использование Сервиса, который содержит список ранее введенных адресов электронной почты.

+0

Спасибо, это ** точно **, что я искал! Все еще изучая все хорошие вещи в AngularJS. Наверное, я не понимал, что вы можете просто получить доступ к сфере действия прямо в функции ссылок, как это. :) – Janne

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