2015-05-13 2 views
0

Я пытаюсь выяснить, как работает AngularJS (или должен работать). Я имею в виду очень простое приложение с заголовком, основным контентом и нижним колонтитулом. Основной контент имеет mainCtrl, который содержит большинство данных (на данном этапе нет службы). Я построил верхний и нижний колонтитулы в качестве директив, вне основного содержимого div. Возможно ли (или рекомендуется) доступ и изменение (привязка) переменных mainCtrl из моих директив? Я прочитал этот контроллер и контроллер. Создайте копию контроллера, в то время как требование может быть тем, что я хочу. Но я не могу заставить его работать. Возможно, некоторая информация и указание на правильное направление могли бы помочь. PS Лучше ли каждый контроллер получать данные с помощью службы/фабрики? Если да, не было бы эффективным хранить некоторые данные в контроллере, а не постоянно звонить службе? Пожалуйста, дайте мне знать, если вам нужно какое-либо разъяснение.Как связать с контроллером vars из директив sibling

* EDIT: Демо здесь: plunker Demo

<!DOCTYPE html> 

<head> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <title>My AngularJS App</title> 
    <meta name="description" content=""> 
    <link rel="stylesheet" href="bower_components/angular-material/angular-material.css"> 
    <link rel="stylesheet" href="app.css"> 
</head> 
<body ng-app="menuApp"> 
<div header-directive></div> 
<hr/> 
<div style="min-height: calc(100vh - 400px)" ng-controller="MainController as main"> 

    <p>Direct access to (mainCtrl) SCOPE user: {{ user }}</p> 
    <p>Direct access to mainCtrl user: {{ main.user }}</p> 

<ul> 
    <li ng-repeat="item in main.menuItems"><a ng-href="#/{{ item.toLowerCase() }}">{{ item }}</a></li> 
</ul> 
<!--<img src="http://ost2.gr/files/gimgs/1_random2.png">--> 
<ng-view></ng-view> 
</div> 

<div footer-directive></div> 

Below footer: {{ main.user }} 

<script src="bower_components/angular/angular.js"></script> 
<script src="bower_components/angular-animate/angular-animate.js"></script> 
<script src="bower_components/angular-material/angular-material.js"></script> 
<script src="bower_components/angular-aria/angular-aria.js"></script> 
<script src="bower_components/angular-route/angular-route.js"></script> 
<script src="app.js"></script> 
<script src="menuApp.config.js"></script> 
<script src="mainController.js"></script> 
<script src="ProductsController.js"></script> 
<script src="ChartsController.js"></script> 
<script src="AboutController.js"></script> 
<script src="footerDirective.js"></script> 
<script src="headerDirective.js"></script> 
</body> 
</html> 

Главный контроллер:

(function() { 
    'use strict'; 

    angular 
     .module('menuApp') 
     .controller('MainController', MainController); 

    MainController.$inject = ['$scope']; 

    /* @ngInject */ 
    function MainController($scope) { 
     /* jshint validthis: true */ 
     var vm = this; 

     vm.activate = activate; 
     vm.title = 'main'; 

     activate(); 

     //////////////// 

     function activate() { 
      vm.menuItems = ['Main', 'Products', 'Charts', 'About']; 
      $scope.user = 'SCOPE USER'; 
      vm.user = 'user from MainController'; 
     } 
    } 
})(); 

Директива заголовка:

(function() { 
     'use strict'; 

     angular 
      .module('menuApp') 
      .directive('headerDirective', headerDirective); 

     headerDirective.$inject = ['$window']; 

     /* @ngInject */ 
     function headerDirective($window) { 
      // Usage: 
      // 
      // Creates: 
      // 
      var directive = { 
       //link: link, 
       restrict: 'EA', //This means that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements 
       replace: true, 
       templateUrl: "header.html" 
       //require: '^MainController' 
       //scope: { user: '=' } 
       ,controller: 'MainController' 
       ,controllerAs: 'main' 
      }; 
      return directive; 

      //function link(scope, element, attrs) { 
      //} 
     } 
    })(); 

Footer Директива:

(function() { 
    'use strict'; 

    angular 
     .module('menuApp') 
     .directive('footerDirective', footerDirective); 

    footerDirective.$inject = ['$window']; 

    /* @ngInject */ 
    function footerDirective($window) { 
     // Usage: 
     // 
     // Creates: 
     // 
     var directive = { 
      //link: link, 
      restrict: 'EA', 
      replace: true, 
      templateUrl: 'footer.html', 
      require: "^headerDirective" 
      //scope: {'main.user': '='}, // This is one of the cool things :). Will be explained in post. 
      //,controller: 'MainController' 
      //,controllerAs: 'main' 
     }; 
     return directive; 

     //function link(scope, element, attrs) { 
     //} 
    } 
})(); 
Шаблон

Заголовок: шаблон

<div> 

    <p>Scope user: {{ user }} </p> 

    <p>Main user: {{ main.user }}</p> 
    <hr/> 

    <p> 
     This part of the header is always here 
    </p> 

    <p ng-if="user"> 
     User is logged in :D 
    </p> 

    <p ng-if="!user"> 
     Hey buddy, log in! Be cool 
    </p> 
    <hr/> 

    <p>Scope user: <input ng-model="user"> {{ user }}</p> 

    <p>Main user: <input ng-model="main.user"> {{ main.user }}</p> 

</div> 

Footer:

<md-toolbar class="md-medium-tall"> 
    <div layout="row" layout-align="center center" flex> 
     <span>FOOTER</span> 
    </div> 
    $SCOPE USER: {{ user }} 
    <hr/> 
    MAIN USER: {{ main.user }} 
</md-toolbar> 
+0

Не могли бы вы обеспечить plunker с вашим фактическим приложением? В любом случае, я чувствую, что вы хотите настроить изолированный объем вашей директивы. Взгляните на https://docs.angularjs.org/guide/directive на части с выделенным областью. – Okazari

ответ

0

Если ваши директивы, сидя за пределами DIV контроллера, вы не сможете получить доступ к возможности вашего контроллера независимо от того, как вы будете настройте область действия директив.

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

, например

<div ng-controller="ParentCtrl"> 
    <div header-directive></div> 
    <div ng-controller="ChildCtrl"> 
    </div> 
    <div footer-directive></div> 
</div> 
+0

Что я имею в виду, это большое приложение. Он может содержать 5-6 вкладок, а основная область содержимого изменяется в соответствии с выбранной вкладкой. Некоторым или всем из них может потребоваться доступ к тем же данным, чтобы читать или изменять их. Обычно я пытаюсь работать без переменных переменной. Возможно ли или рекомендуется, чтобы у меня было много директив, каждый со своим собственным шаблоном, но один и тот же контроллер привязан к ним? Чтобы они могли получать и изменять значения, связанные с этим контроллером? (Я знаю, что это не задача контроллера держать vars и т. Д., Но я пытаюсь получить большую картину) – Tsafou

+0

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

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