Javascript AngularJS:ng包括和ng控制器

Javascript AngularJS:ng包括和ng控制器,javascript,angularjs,angularjs-scope,angularjs-ng-include,Javascript,Angularjs,Angularjs Scope,Angularjs Ng Include,我有一个应用程序,我正在建设的角度,我有大约8-10个意见,以建立出来。 所有视图都有一个共享的页脚,基于视图和一组业务规则,我需要有条件地显示/隐藏页脚上的一些内容 所以。 我为每个视图设置了控制器,然后为页脚设置了一个控制器。 我使用ng include包含公共页脚布局,其中包含的html引用ng控制器中的页脚控制器 Index.html <body ng-controller="MainCtrl as vm"> <p>Message from Main Co

我有一个应用程序,我正在建设的角度,我有大约8-10个意见,以建立出来。 所有视图都有一个共享的页脚,基于视图和一组业务规则,我需要有条件地显示/隐藏页脚上的一些内容

所以。 我为每个视图设置了控制器,然后为页脚设置了一个控制器。 我使用ng include包含公共页脚布局,其中包含的html引用ng控制器中的页脚控制器

Index.html

<body ng-controller="MainCtrl as vm">
    <p>Message from Main Controller '{{vm.mainMessage}}'</p>
    <div ng-include="'commonFooter.html'"></div>
</body>
然后,我打算在FooterController中返回父控制器,并拉出特定设置,以根据业务规则启用/禁用内容

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

  window.console.log('Footer scope id: ' + $scope.$id);
  window.console.log('Footer parent scope id: ' + $scope.$parent.$id);
  window.console.log('Footer grandparent scope id: ' + $scope.$parent.$parent.$id);
  window.console.log('Footer grandparent scope name: ' + $scope.$parent.$parent.mainMessage);
  window.console.log('Footer grandparent scope condition: ' + $scope.$parent.$parent.shouldDisplaySomthingInFooter);

  vm.showSomthing = false; //how to pull from parent scope to bind the ng-show to a value set in the parent from within a ng-include?
});
我这里有一个例子:

我发现,当我进入父范围取出内容时,它会返回为未定义的内容,我不知道为什么

通过检查scopeid,我可以看到作用域嵌套到了祖辈级别,我相信这是因为ng include在视图作用域下面添加了一个额外的作用域层。

额外要点:如果我不必使用$scope对象,并且可以坚持使用
var vm=this这样做的方式更好。但乞丐不能挑肥拣瘦:)


非常感谢。您误解了controller as syntax()的用途。这只是在本地作用域上公开特定控制器的一种方法,以便您可以从模板访问其属性。当您在父模板和页脚模板中使用
someController作为vm
时,您不会以某种方式在控制器之间创建连接或诸如此类的连接。您只是在页脚的作用域上设置了一个
vm
属性,因此当您在页脚模板中使用它时,您正在访问页脚的控制器(并且您已经阻止了到父控制器的路径)

对于您试图做的事情,基本上不需要控制器作为语法。只需将数据正确地放在
$scope
上,让scope层次结构为您完成其余的工作

在父控制器中:

$scope.features.rock = true;
$scope.features.roll = false;
在页脚模板中

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


您现在还可以查看和更改其他控制器的
功能(因为它们的作用域是父控制器作用域的后代)。

我摆弄了您的plunker,但也更改了
var vm=this
$scope
,所以我在额外的点上失败了:-)

我强烈建议不要使用
$scope.$parent
,这正是您显示的原因。各种指令,如
ng include
ng show
等,都会生成自己的作用域

如果将来有人有意或无意地更改您的html并添加范围,您将无法控制

我建议使用驻留在
MainCtrl
上的函数,并通过继承作用域访问它们

并称之为:

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

如果将外部控制器的作用域设置为
vm
,将内部控制器的作用域设置为
foo
,则可以轻松地将它们分开,并在内部控制器中引用vm

HTML

<body ng-controller="MainCtrl as vm">
    <p>Message from Main Controller '{{vm.mainMessage}}'</p>
    <div ng-include="'commonFooter.html'"></div>
</body>
<div ng-controller="FooterCtrl as footer">
    <p>Message from Footer Controller '{{footer.message}}'</p>
    <p ng-show="vm.shouldDisplaySomethingInFooter">Conditional footer Content</p>
</div>
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';
});
注意:为了清晰起见,并减少视图和控制器之间的混淆,我将您的
var vm=this
重命名为
var self=this

预期产出:

<p ng-show="getShouldShow();">Conditional footer Content</p>
  window.console.log('Footer grandparent scope name: ' + $scope.getMainMessage());
  window.console.log('Footer grandparent scope condition: ' + $scope.getShouldShow());
<body ng-controller="MainCtrl as vm">
    <p>Message from Main Controller '{{vm.mainMessage}}'</p>
    <div ng-include="'commonFooter.html'"></div>
</body>
<div ng-controller="FooterCtrl as footer">
    <p>Message from Footer Controller '{{footer.message}}'</p>
    <p ng-show="vm.shouldDisplaySomethingInFooter">Conditional footer Content</p>
</div>
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';
});