AngularJS : ng-include and ng-controller

大兔子大兔子 提交于 2019-11-28 21:11:23
Kyle Muir

If you scope your outside controller as vm and your inside controller as foo, you can then separate them easily and refer to vm within the inside controller.

Demo

HTML:

<body ng-controller="MainCtrl as vm">
    <p>Message from Main Controller '{{vm.mainMessage}}'</p>
    <div ng-include="'commonFooter.html'"></div>
</body>

CommonFooter.html:

<div ng-controller="FooterCtrl as footer">
    <p>Message from Footer Controller '{{footer.message}}'</p>
    <p ng-show="vm.shouldDisplaySomethingInFooter">Conditional footer Content</p>
</div>

app.js:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function() {
    var self = this;
    self.mainMessage = 'Hello world';
    self.shouldDisplaySomethingInFooter = true;
});

app.controller('FooterCtrl', function() {
    var self = this;
    self.message = 'vm footer';
});

Note: I renamed your var vm = this to var self = this for clarity and to reduce confusion between your views and your controllers.

Expected output:

You've misunderstood what the controller as syntax (see documentation) is used for. It is just a way to expose a particular controller on your local scope, so that you can access its properties from a template. When you use someController as vm in both your parent and footer templates, you don't somehow create a connection between the controllers or anything like that. You're just setting a vm property on your footer's scope, so when you use it in your footer template, you're accessing the footer's controller (and you've blocked your way to the parent controller).

For what you're trying to do, you basically don't need the controller as syntax at all. Just properly put your data on $scope and let the scope hierarchy do the rest for you.

In your parent controller:

$scope.features.rock = true;
$scope.features.roll = false;

In your footer template

<p ng-show="features.rock">...</p>
<p ng-show="features.roll">...</p>

You can now also see and change the features from your other controllers (as their scopes are descendants of parent controller's scope).

I fiddled around with your plunker, but also changed var vm = this; to $scope, so I'm failing at extra points :-)

I would strongly advise against the usage of $scope.$parent exactly for the reason you show. Various directives such as ng-include, ng-show etc, generate their own scopes.

You have no control if someone in the future changes your html and adds scopes, intentionally or otherwise.

I recommend using functions that reside on your MainCtrl and accessing them via inheriting scopes.

Plunker

$scope.getShouldShow = function() {
    return $scope.shouldDisplaySomthingInFooter;
  };
  $scope.setShouldShow = function(val) {
    $scope.shouldDisplaySomthingInFooter = val;
  };

  $scope.getMainMessage = function () {
    return $scope.mainMessage;
  }

And calling them:

<p ng-show="getShouldShow();">Conditional footer Content</p>

And:

  window.console.log('Footer grandparent scope name: ' + $scope.getMainMessage());
  window.console.log('Footer grandparent scope condition: ' + $scope.getShouldShow());
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!