[英]AngularJS : ng-include and ng-controller
I have an app which I am building with angular, I have about 8-10 views to build out. 我有一个应用程序,我正在构建角度,我有大约8-10个视图来构建。 All the views have a shared footer, based on the view and a set of business rules i need to conditionally show / hide some of the content on the footer.
所有视图都有一个共享的页脚,基于视图和一组业务规则,我需要有条件地显示/隐藏页脚上的一些内容。
So. 所以。 I have controllers for each view, and then one for the footer.
我有每个视图的控制器,然后一个页脚。 I include the common footer layout using ng-include, where the html I am including references the footer controller in the ng-controller.
我使用ng-include包含公共页脚布局,其中我包含的html引用了ng-controller中的页脚控制器。
Index.html 的index.html
<body ng-controller="MainCtrl as vm">
<p>Message from Main Controller '{{vm.mainMessage}}'</p>
<div ng-include="'commonFooter.html'"></div>
</body>
commonFooter.html commonFooter.html
<div ng-controller="FooterCtrl as vm">
<p>Message from Footer Controller '{{vm.message}}'</p>
<p ng-show="vm.showSomthing">Conditional footer Content</p>
</div>
I want each views controller to determine the state of the footer and whether specific content is hidden or not. 我希望每个视图控制器确定页脚的状态以及是否隐藏特定内容。 (shouldDisplaySomthingInFooter below)
(下面的shouldDisplaySomthingInFooter)
app.controller('MainCtrl', function($scope) {
var vm = this;
vm.mainMessage= 'HEELO';
vm.shouldDisplaySomthingInFooter = true;
window.console.log('Main scope id: ' + $scope.$id);
});
Then i had intended that in the FooterController would reach back into the parent controller and pull out the specific settings to enable / disable content based on the business rules. 然后我打算在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?
});
I have this example here: http://plnkr.co/edit/ucI5Cu4jjPgZNUitY2w0?p=preview 我在这里有这个例子: http : //plnkr.co/edit/ucI5Cu4jjPgZNUitY2w0?p = preview
What I am finding is that I when I reach into the parent scope to pull out the content it is coming back as undefined, and I am not sure why. 我发现的是,当我进入父作用域以取出它作为未定义的内容时,我不知道为什么。
I can see that the scopes are nested to the grandparent level by checking the scopeid, I believe this is because the ng-include adds an extra scope layer below the view scopes. 通过检查scopeid,我可以看到范围嵌套到祖父级别,我相信这是因为ng-include在视图范围下面添加了一个额外的范围层。
Extra points: If i can not have to use the $scope object and can stick with the var vm = this;
额外点:如果我不能使用$ scope对象并且可以坚持使用
var vm = this;
way of doing it that would be preferable. 这样做的方式更可取。 But beggars cant be choosers :)
但是乞丐不能选择:)
app.controller('MainCtrl', function($scope) {
var vm = this;
Thank you very much in advance. 非常感谢你提前。
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. 如果将外部控制器作为
vm
并将内部控制器作为foo
,则可以轻松地将它们分开并引用内部控制器中的vm。
HTML : HTML :
<body ng-controller="MainCtrl as vm">
<p>Message from Main Controller '{{vm.mainMessage}}'</p>
<div ng-include="'commonFooter.html'"></div>
</body>
CommonFooter.html : 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 : 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. 注意:为了清楚起见,我将
var vm = this
重命名为var self = this
,以减少视图与控制器之间的混淆。
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. 当您在父模板和页脚模板中使用
someController as vm
时,您不会以某种方式在控制器之间创建连接或类似的东西。 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). 您只是在页脚范围内设置
vm
属性,因此当您在页脚模板中使用它时,您正在访问页脚的控制器(并且您已阻止前往父控制器的方式)。
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. 只需将数据正确放在
$scope
,让范围层次结构为您完成剩下的工作。
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). 您现在还可以查看和更改其他控制器的
features
(因为它们的范围是父控制器范围的后代)。
I fiddled around with your plunker, but also changed var vm = this;
我摆弄你的羽毛球,但也改变了
var vm = this;
to $scope
, so I'm failing at extra points :-) $scope
,所以我没有加分:-)
I would strongly advise against the usage of $scope.$parent
exactly for the reason you show. 我强烈建议不要使用
$scope.$parent
,因为你显示的原因。 Various directives such as ng-include
, ng-show
etc, generate their own scopes. 诸如
ng-include
, ng-show
等各种指令生成它们自己的范围。
You have no control if someone in the future changes your html and adds scopes, intentionally or otherwise. 如果将来某人有意或无意地更改您的HTML并添加范围,您无法控制。
I recommend using functions that reside on your MainCtrl
and accessing them via inheriting scopes. 我建议使用驻留在
MainCtrl
上的函数,并通过继承范围访问它们。
$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());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.