你能更新一个控制器来更新它的子范围吗?

Can you update a controller that updates it's child scopes?

假设我有一个这样的控制器和指令:

app.controller('mainController', function($scope) {
    $scope.loading = true;
    $scope.updateTest = function(){
        $scope.loading = false;
    }
}).directive('loading', function() {
    return {
        restrict : 'E',
        transclude: true, // use parent scope
        link : function(scope, element, attrs) {
            scope.$watch('loading', function(ctx) {
                console.log('updating?', ctx)
            });
        }
    }
});

还有一个 html 标记:

<section ng-controller="mainController">
    <loading ng-show="loading">
        loading?
    </loading>
    <button ng-click="updateTest()">Force update</button>
</section>

我只想知道如何从指令中查看父范围,我似乎无法正常工作!

我正在使用 Angular 1.3.16

我建议你像这样使用隔离范围并将所有变量传递给它:

.directive('loading', function() {
  return {
    restrict : 'E',
    scope: {
      ngModel: '='
    },
    transclude: true, // use parent scope
    link : function(scope, element, attrs) {
        scope.$watch('ngModel', function(ctx) {
            console.log('updating?', ctx)
        });
    }
  }
});

Html

<loader ng-model="loading" ng-show="loading">
    loading?
</loader>

如果您使用 scope:false 参数创建一个指令,它将使用它的父范围,因此您可以访问和操作父范围内的所有内容。但是您正在使您的指令与父范围紧密耦合,这是不推荐的。我建议您使用隔离范围并为此操作使用参数。通过使用隔离范围,您的指令将可重复使用

这里是父作用域的使用方法

.directive('loading', function() {
return {
restrict : 'E',
scope: false, // use parent scope
transclude: true,
link : function(scope, element, attrs) {
    scope.$watch('loading', function(ctx) {
        console.log('updating?', ctx)
    });
 }
}
 });

编辑:正如评论中提到的@zeroFlogL,不添加作用域是angular 的默认行为。如果您从指令中删除 scope: false 部分,它将与 scope:false

相同

当您像 Tek 的回答(我也建议这样做)那样使用隔离作用域时,最好使用您自己的属性名称而不是 ngModel,这只会导致 angular 的开销处理 ngModel 指令的编译和 link(控制器)步骤。

诚然,它很挑剔,但与 angular 一起工作时,我认为考虑表面下发生的事情很有用。最后,所有发生的 angular 魔术都不是 "free of charge" 并且当您使用真正的大数据集并使用 n 生成指令实例时 ng-repeat,根据我的经验,不必要的控制器实例和手表会很快增加性能。