2015-10-20 2 views
0

У меня есть 2 элемента, как так:Angularjs: Как получить доступ к области контроллера в директиве?

<div ng-hide="showDiv"></div> 
<div ng-show="showDiv"> 
    <div directive></div> 
</div> 

И директиву, как так:

app.directive ('directive', [ 
    ... 
    controller: [ 
     '$scope', 
     function ($scope) { 
      $scope.accept = function() { 
      $scope.showDiv = false; 
      }; 
     } 
     ], 
    .... 
] 

Я пытался использовать $ scope.showDiv в директиве, чтобы переключить контроллер, но он не работает , Как получить доступ к области контроллера в рамках директивы?

console.log ($ scope) в директиве показывает $ scope.showDiv === false, хотя $ scope.showDiv === true в контроллере.

+2

Это один из многих случаев наиболее часто недооцениваемых аспектов углового. '$ scope.showDiv' не является объектом, он является примитивным и не соблюдает те же правила для наследования прототипа JavaScript. Это одно из многих мест, где вступает в действие кардинальное правило углового «Всегда использовать точку в привязках». см. http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs для глубокого погружения по предмету. – Claies

+2

_sidenote_ похоже, что у вас есть [неправильное название директивы] (https://docs.angularjs.org/guide/directive#matching-directives), это должно быть так: 'app.directive ('showMeTheDivDirective', ...' – Grundy

ответ

0
$scope.showDiv = true 

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

//controller 
//change primitive to object 
$scope.showDiv = {status: true}; 

//template 
//directive names in HTML are usually in kebab case but i'm keeping it obvious for now. 
//Pass showDiv object to directive 
<div ng-show="showDiv.status"> 
    <div directive showDiv="showDiv"></div> 
</div> 

//directive 
app.directive ('directive', [ 
    ... 
    return { 
    scope : { 
     //bind directive scope to parent 
     showDiv: '=showDiv' 
    } 
    controller: [ 
     '$scope', 
     function ($scope) { 
      $scope.foo = function() { 
      //Changing object in directive will also update parent scope. 
      $scope.showDiv.status = false; 
      }; 
     } 
     ], 
    .... 
] 

//controller 
//after $scope.foo executed in directive 
console.log(showDiv) === {status: false} 
1

Вы можете просто добиться этого, если используете синтаксис controllerAs.

HTML

<div ng-hide="showDiv"></div> 
<div ng-show="showDiv"> 
    <div dir-show-div is-shown="showDiv"></div> 
</div> 

Директива

angular 
    .module('app') 
    .directive('dirShowDiv', dirShowDiv); 

function dirShowDiv() { 
    var directive = {}; 

    directive.scope = { 
     isShown: '=' 
    }; 
    directive.controller = 'DirController'; 
    directive.controllerAs = 'vm'; 

    return directive; 
} 

Директива Контроллер

angular 
    .module('app') 
    .controller('DirController', DirController); 

function DirController() { 
    var self = this; 

    self.accept = accept; 

    function accept() { 
     self.isShown = false; 
    } 
} 
+0

Почему вы перемещаете 'showDiv' из' $ scope', как в OP для контроллера? – Grundy

+0

@Grundy Я ожидал, что OP использует его в контроллере как '$ scope.showDiv'. Я сделаю редактирование. –

+0

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

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