如何从兄弟指令

时间:2015-05-13 09:42:57

标签: angularjs angularjs-directive

我想弄清楚AngularJS是如何工作的(或者应该工作)。我想到了一个非常简单的应用程序,包含标题,主要内容和页脚。主要内容有一个mainCtrl,可以容纳大部分数据(此阶段没有服务)。我在主要内容div之外构建了页眉和页脚作为指令。是否可以(或推荐)从我的指令访问和更改(绑定)mainCtrl变量?我读了那个控制器和控制器,创建了一个控制器的副本,而需要可能是我想要的。但我无法让它发挥作用。也许一些信息并指向正确的方向可能会有所帮助。 PS让每个控制器使用服务/工厂获取数据会好得多吗?如果是,将一些数据存储在控制器中而不是一直调用服务是否有效? 如果您需要任何澄清,请告诉我。

*编辑:在这里演示: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) {
            //}
        }
    })();

页脚指令:

(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>

页脚模板:

<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>

1 个答案:

答案 0 :(得分:0)

如果你的指令位于控制器div之外,无论你如何配置指令范围,你都将无法访问控制器的范围。

您可以使用服务并将服务注入MainCtrl和指令,或者您的用例的一个好习惯是将一个Parent控制器放在您的应用程序的全局范围内。然后,将指令范围配置为从父控制器继承

例如

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