Angular JS: привязка в ng-show не работает

У меня есть директива и контроллер:

app.directive('responseBox', function(){
return {
    restrict: 'E',
    transclude: true,
    templateUrl: 'responseBox.html',
    link: function(scope, element, attrs) {
        element.bind("click", function () {
            scope.toggle();
        })
    }
}});

и контроллер:

app.controller('responseBoxCtrl', function($scope) {
$scope.opened = false;
$scope.toggle = function() {
    $scope.opened = !$scope.opened;
    console.log($scope.opened);
}});

responseBox.html:

<div class="promptBlockResponse" ng-transclude>
<div class="btn-toolbar" style="text-align: right;">
    <div class="btn-group" ng-show="opened">
        <a class="btn btn-link" href="#"><i class="icon-pencil icon-white"></i></a>
        <a class="btn btn-link" href="#"><i class="icon-remove icon-white"></i></a>
    </div>
</div>          

И в основном html файле:

<response_box ng-controller="responseBoxCtrl"></response_box>

Я хочу, чтобы группа btn показывала, когда открытая переменная истинна. Когда я нажимаю responseBox, я вижу переменную, но группа btn не отображается/скрывается. Что мне не хватает?

Ответ 1

Итак, повторяя то, что Джош и я сказал в комментариях выше, обработчик кликов работает "снаружи" Angular, поэтому вам нужно вызвать scope.$apply(), чтобы вызвать Angular для запуска цикла дайджеста, чтобы заметить изменение, которое было сделано для scope (и затем обновит ваше представление):

$scope.toggle = function() {
    $scope.opened = !$scope.opened;
    console.log($scope.opened);
    $scope.$apply();
}});

Функция ссылки может быть устранена с помощью ng-click в шаблоне:

<div class="promptBlockResponse" ng-transclude ng-click="toggle()">

Ответ 2

С Angular 1.3 и 1.2 следующий фрагмент из HTML-шаблона для директивы настраиваемого элемента:

<div ng-click="toggle($event)"></div>
<div ng-show="data.isOpen"></div>

И фрагмент из контроллера для этой настраиваемой директивы:

$scope.toggle = function ($event, destinationState) {
....
data.isOpen = true; //this is in scope and a digest cycle is already running
//calling $scope.$apply will cause an error

демонстрирует сценарий в области видимости, в котором вам нужно использовать $apply.

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

<div ng-show="{{data.isOpen}}">

Переход на

 <div ng-show="data.isOpen"></div>

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

Итак, в Angular 1.2 и 1.3 ng-click не "снаружи" Angular, по крайней мере, используя подпись, которую я использовал для моей функции toggle, и объясняется здесь: $применить уже выполненную ошибку

Я обнаружил, что проблема с ng-show с двойной привязкой, которую я изначально считал проблемой с областью, благодаря этому SO: почему ng-show удалить класс ng-hide