更新 2: 现在我对 AngularJS 有了更多的了解,这是一个更好的答案。
假设我想在 switch-case 之外访问 todoText(在 switch-case 内部),我该怎么做呢?
父作用域无法访问子作用域。(根据 Angular 开发人员的说法,这种限制的一个原因是为了更容易地对范围进行内存管理。)(嗯,你可以使用 $$childHead 和 $$childTail 来访问子范围,但你不应该这样做!)
我是否可以将 switch-case 范围绑定到模型,它是否可以通过其他方式访问,或者应该以其他方式解决?
从子作用域访问父模型的常用方法有以下三种:
- 执行@Gloopy 建议的操作:在父范围内创建一个对象,然后在子范围内引用该对象的属性。
- 在子作用域中使用 $parent 来访问父作用域及其属性,甚至是原始属性。
- 在父作用域上调用方法
要将您的小提琴转换为使用 $parent:
<input type="text" ng-model="$parent.todoText" ...
$scope.addTodo = function() {
$scope.todos.push({text: $scope.todoText, ...
$scope.todoText = '';
正如我在 Gloopy 答案的评论中提到的那样,ng-repeat 和 ng-switch 都有新的子作用域原型继承自父作用域。ng-repeat 还将循环变量/项目复制到新的子范围(以及@Gloopy 用原语与对象描述的细微差别适用)。ng-switch 不会从父范围复制任何内容。
要查看内部/子范围的外观,请在 ng-switch-when 之后添加以下内容:
<a ng-click="showScope($event)">show scope</a>
并将其添加到您的控制器:
$scope.showScope = function(e) {
console.log(angular.element(e.srcElement).scope());
}
更新1:(删除线添加到不好的建议,[]为清楚起见添加)
对于这种情况,AngularJS 正在创建额外的内部范围(隐式),而您并不真正想要/需要另一个控制器,我喜欢 Gloopy 的解决方案。服务(我最初在下面建议的)是 [执行此操作的错误方法]在这里可能有点矫枉过正。我也喜欢 Gloopy 的解决方案不需要在控制器方法中使用“this”。
原始答案:(为不良建议添加了删除线,为清楚起见添加了[])
要查看创建范围的位置(如果您还没有尝试过,这很方便):
.ng-scope { margin: 4px; border: 1px dashed red }
要在 switch-case 之外访问 todoText(因此在其范围之外),您实际上是在询问控制器间通信,因为涉及多个范围。您有几个选择,但服务可能是最好的。将数据(需要共享的)存储在服务中,并将该服务注入需要访问数据的每个控制器。
对于您的具体示例,我认为您需要将一个控制器附加到每个开关盒并将服务注入其中,以访问共享数据。
另请参阅AngularJS:如何在控制器之间传递变量?.
其他选项:
不推荐在内部范围内使用 $scope.$parent [执行此操作的一种方法——参见上面的 Update2] ,因为那时控制器将对数据的呈现方式做出假设。
不建议使用 $rootScope,除非可能用于简单的一次性应用程序。共享数据可能会开始拥有自己的生命,而 $rootScope 不是发生这种情况的地方。服务更容易重用、添加行为等。
使用 $scope.$emit 是另一种选择,但它看起来很混乱而且有点奇怪:发出事件来共享数据(而不是触发行为)。
[在父范围内使用对象可能是最好的——请参阅@Gloopy 的答案。]