0

Я создаю настраиваемую угловую директиву для слайд-меню в меню, которое должно смотреть несколько атрибутов, и один из этих атрибутов должен быть двухсторонним к области основного контроллера (иногда). Однако иногда атрибут не добавляется разработчиком, поэтому его необходимо добавить автоматически и установить на значение по умолчанию (false). Таким образом, директива может быть использована следующим образом.Угловая пользовательская директива - двусторонняя привязка, которая всегда устанавливает атрибут true или false

<slide-menu position="right" is-open="menuIsOpen"></slide-menu> 

или как это:

<slide-menu></slide-menu> 

При использовании первого способа основной контроллер будет иметь возможность открыть и закрыть меню, изменив значение логического $ scope.menuIsOpen.

При использовании без подачи атрибута is-open он должен иметь значение по умолчанию false и, очевидно, используется внутренне и директивой toggle для детей.

Дополнительным осложнением является то, является ли атрибут предоставленным разработчиком или нет, он должен существовать в DOM. поэтому во втором примере выше директива по умолчанию установит значение false и добавит атрибут is-open = "false" в DOM?

Причина требующий является открытой = «ложь/истина» в DOM во все времена, что меню фактически управляется с помощью CSS tansitions, которые используют следующий селектор:

slide-menu[is-active="true"]{ 
    // Slide the menu in using transforms/transitions 
} 

Там является jsfiddle здесь, который показывает, как далеко я получил.

http://jsfiddle.net/jonhobbs/gEPvE/

Очевидно, что это не работает, но он показывает, как я попытался установить по умолчанию, и как я пытался использовать @ и & на изолированном объеме в течение одного времени связывания (положение меню) и двунаправленное выражение для открытой переменной.

Мне явно далеко от достижения того, что мне нужно, но любой совет будет действительно оценен.

ответ

1

Посмотрите на эту скрипту http://jsfiddle.net/gEPvE/38/ Я взял тот, который вы начали, и обновил его, чтобы действовать так, как вы указали.

Вы можете сделать двунаправленное значение привязки необязательным, добавив? по определению области.

Как это

{ 
    scope: { 
     'isOpen':'=?' 
    } 
} 

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

Далее, чтобы синхронизировать атрибут DOM со значением области, вы можете использовать $ watch.

$scope.$watch('isOpen', function(val) { 
    $element.attr('is-open', val); 
}); 

Наконец, я изменил вторую директиву «slideMenuToggle», чтобы обернуть/transclude его элемент, чтобы добавить обработчик нг щелчок. Это в основном для того, чтобы избежать любой гадости с вызовом $ scope. $ Apply.

Сообщите мне, если это сработает для вас.


EDIT

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

Например

<div ng-controller='ctrl'> 
    <hello world='imOnScope'></hello> 
</div> 

Если предположить, что 'привет' директива с рамкой 'мир': '? =' то угловой присваивает ссылку объекту «imOnScope» родительской области на объект переменной $ scope.world директивы, позволяя сценарий двухсторонней привязки.

Чтобы просто предоставить значение непосредственно вы можете сделать что-то вроде этого

<div ng-controller="ctrl"> 
    <hello world="'directValue'"></hello> 
</div> 

В этом случае угловой просто назначить «directValue» члену $ scope.world в директивы.

+0

Спасибо Скотту, что почти работает именно так, как я хочу, чтобы он работал. Что-то я могу не понимать правильно, хотя, если я хочу использовать =? означает ли это, что атрибут должен быть привязан к чему-то в области видимости? Если бы я хотел, чтобы разработчик мог использовать position = "right", чтобы просто установить значение OR position = "position", чтобы связать его с $ scope.position, есть ли способ сделать это? в основном я хочу, чтобы разработчик мог просто установить атрибут или связать его с областью, что им больше подходит. – jonhobbs

+0

Проверьте изменения и посмотрите, отвечает ли это на ваш вопрос. Благодарю. –

0

Причиной требующих является открытой = «ложь/истина» в DOM во все времена является то, что меню на самом деле работает используя CSS-тангажи, которые используют следующий селектор

Принудительная директива атрибута utes подходит для селекторов css - ужасная идея. Как вы правильно заявили, они предназначены для разработчиков. Поэтому добавьте класс в элемент динамически.

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

Я думаю, это может быть что-то вроде this (только что добавлено ngTouch и ng-controller для родительской области).


Вы могли бы заменить

$scope.watch('isOpen', function() { 
    $element.toggleClass('opened', $scope.isOpen); 
}); 

с

$scope.watch('isOpen', function() { 
    $attrs.isOpen = !!$scope.isOpen; 
}); 

и получить информацию о поведении вы просите, легко, как это. Ок, теперь это логическое значение, и оно отражает область действия, и вы можете использовать селектор [is-open=true]. Но угадайте, что произойдет с вашей привязкой? Разбитый. К счастью, вы можете сделать

$scope.watch('isOpen', function() { 
    $element.attr('is-open', !!$scope.isOpen); 
}); 

вместо этого. Вуала, мы обманули Угловое, потому что он не заботится о jqlite. Но что будет с привязкой, когда директива будет перекомпилирована по какой-либо причине? Опять же, привязка isOpen является несуществующей переменной «true» или «false». Разбитый.

+0

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

+0

Кроме того, если я использую привязку @, это будет только один способ и что-то внутреннее в директиве (например, управление переключением детей), чтобы изменение isOpen не распространялось на область родительского контроллера, верно? – jonhobbs

+0

Да, '@' предполагает, что вам не нужно сообщать о состоянии isOpen. Конечно, вы можете использовать '=' (и тогда будет 'is-open =" mainMenuOpen "', но он изменит родительскую область, даже если она вам не понадобится, чтобы избежать использования вместо этого 'getMainMenuOpen()' – estus

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