2016-06-16 3 views
0

Я реализую раскрывающееся меню, для которого я пишу свою собственную директиву. Я не использую какой-либо элемент ввода, поэтому не использую ngModel. Возможна ли двусторонняя привязка к пользовательским атрибутам?Двусторонняя привязка в пользовательской директиве без использования NgModel. Возможное?

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

 
mainApp.directive('tableDropdown', ['$timeout', 
 
    function($timeout) { 
 
    return { 
 
     restrict: 'C', 
 
     scope: { 
 
     selectedFilter: '=?' 
 
     }, 
 
     link: function(scope, elem, attrs) { 
 
     $timeout(function() { 
 
      angular.element(elem).find('li:first-child').addClass(angular.element(elem).find('li').hasClass('selected') ? '' : 'selected'); 
 
      scope.selectedFilter.cycleStatus = null; 
 
      angular.element(elem).find('li').click(function(e) { 
 
       if (angular.element(this).closest('ul').hasClass('active')) { 
 
       angular.element(this).closest('ul').removeClass('active'); 
 
       scope.selectedFilter.selected = angular.element(this).attr('value'); 
 
       } else { 
 
       angular.element(this).closest('ul').addClass('active'); 
 
       scope.selectedFilter.selected = null; 
 
       } 
 
       angular.element(this).addClass('selected').siblings().removeClass('selected'); 
 
      }) 
 
     }, 0); 
 
     } 
 
    } 
 
    } 
 
])
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<th ng-app="mainApp" ng-init="datefilter.selected=null"> 
 
    --{{datefilter.selected}} 
 
    <ul class="tableDropdown" selected-filter="datefilter.selected"> 
 
    <li value="null" class="default"><span>Cycle Status</span> 
 
    </li> 
 
    <li value="completed"><span>Completed</span> 
 
    </li> 
 
    <li value="cancelled"><span>Cancelled</span> 
 
    </li> 
 
    </ul> 
 
</th>

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

Я хочу получить выбранное значение в datefilter.selected, а затем использовать его, чтобы сделать что-то еще. Возможно ли это? Если нет, обходной путь?

+0

Да, двухсторонняя привязка очень возможна, чего вы пытаетесь достичь здесь, при нажатии любого из значений, если параметр datefilter.selected изменился?, Потому что текущий код, похоже, не делает ничего подобного – gaurav5430

+0

Да Я хочу, чтобы он изменил значение. Я обновил код из 'scope.selectedFilter.cycleStatus' до' scope.selectedFilter.selected' – Roy

+0

В качестве примечания стороны, ограничивая директиву классу, обычно не одобряется. – gyc

ответ

1

В настоящее время, не считая кода для установки классов, вы можете использовать приведенный ниже код для изменения datefilter.selected.cycleStatus изнутри directive, и это отразится в пользовательском интерфейсе.

UI:

--{{datefilter.selected.cycleStatus}} 
    <ul class="tableDropdown" selected-filter="datefilter.selected"> 
    <li value="null" class="default"><span>Cycle Status</span> 
    </li> 
    <li value="completed"><span>Completed</span> 
    </li> 
    <li value="cancelled"><span>Cancelled</span> 
    </li> 
    </ul> 

Код:

scope: { 
    selectedFilter: '=' 
    }, 
link: function(scope, elem, attrs) { 

     $timeout(function() { 
      scope.selectedFilter.cycleStatus = null; 
      elem.find('li').click( 
      function(e) { 
       scope.selectedFilter.cycleStatus =angular.element(this).attr('value'); 
       scope.$apply(); 
      }); 


     }, 0); 
     } 

Обратите внимание на scope.$apply(), который отвечает за автоматическое изменение значения в пользовательском интерфейсе (в противном случае оно может отражать поздно после того, как какой-то другой элемент заставляет дайджест цикл)

Вот пример скрипки: http://jsfiddle.net/Lvc0u55v/5503/

+0

Perfect. Большое спасибо. Нельзя было использовать 'scope. $ Apply();'. Раньше я думал, что это необходимо, если вы пишете асинхронные функции, такие как 'setTimeout'. Почему это требуется здесь? – Roy

+0

Это необходимо, когда вы изменяете значения вне углового значения, здесь вы изменяете переменную области видимости внутри функции jquery click, поэтому вам нужно использовать apply() – gaurav5430

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