$范围是全球行事

问题描述:

我想学习指令,我有一堆看起来像我的代码下面的指令。但由于某种原因,如果我定义的每个指令都有一个“$ scope.data”或一个“$ scope.takeInClick”,它似乎从上次加载的指令中获得了定义...

因此,例如如果“$ scope.data ='hello'”在一个指令中,并且“$ scope.data ='hi'”...如果后者指令最后被加载,但是如果我console.log($ scope.data)在前指令,它会显示'嗨',而不是。

这很麻烦,我不知道为什么会发生这种情况?或者如果它的目的是?我想那是$ rootScope的价格,不是 $ scope。我试图在指令定义中注入$ scope,但Angular似乎并不喜欢这样。

有人可以帮助或解释,请谢谢

app.directive('someDirective', function (SomeFactory1, SomeFactory2) { 

var controller = function ($scope) { 

    $scope.data; //Defined in all of my directives 

    function Initialize() { 
     $scope.data = { 
      stuff: '' 
     } 
    } 

    Initialize(); 

    $scope.takeInClick = function() { //Defined in all of my directives too 
     //Do Something 
    } 

}; 

return { 
    templateUrl: 'App_Data/Directives/Something/Something.html', 
    controller: controller 
} 
}); 
+0

阅读有关angular ...'components'的指令或更新版本中的隔离范围。应该是简单的网络搜索 – charlietfl

+0

@charlietfl谢谢你现在看看 – user1189352

+0

@charlietfl如果你把答案我会给你信用。我是谷歌搜索,但没有提到..但你给我正确的条款搜索,我找到了答案,因为它。 TY – user1189352

这是一个有点违反直觉,但在angularJS $范围并不一定是孤立的。您可以在一个控制器中定义一个范围变量,并从同一级别的其他控制器访问它,就好像它是该控制器范围的一部分一样,并且可能既强大又危险。最简单的解决方案是尽可能使用控制器变量和$ scope范围内的语法,但有很多情况下$ scope是正确的选择,通过练习,您将学会识别哪个是合适的。

如果您使用$ scope,则需要记住几个实践。第一个,也许是最重要的,是在语义上和具体上命名变量。如果您的相邻范围具有相似的功能或元素,则使用通用名称会导致问题。我遇到了我的某个指令中出现错误的场景,因为同一页上的另一个指令意外地覆盖了具有相同名称的函数,因此它使用了错误的数据。更具体地说,你也更安全,每次使用这个变量时写一些额外的字符是一个小小的代价,可以让你安心和可读的代码。

另一种解决方案是使用isolated scopes(搜索:隔离指令范围)。一个孤立的作用域的作用更接近你所期望的范围,你在那个作用域级别定义的任何东西都不能在当前作用域及其子域之外访问。但是,您必须小心所分离的范围,因为任何元素只能访问单个隔离范围。如果你有一起工作的属性指令,给他们隔离的作用域会导致编译错误。

一个隔离范围添加到您的代码,你只需把它定义为对象的一部分,就像这样:

app.directive('someDirective', function (SomeFactory1, SomeFactory2) { 

var controller = function ($scope) { 

    $scope.data; //Defined in all of my directives 

    function Initialize() { 
     $scope.data = { 
      stuff: '' 
     } 
    } 

    Initialize(); 

    $scope.takeInClick = function() { //Defined in all of my directives too 
     //Do Something 
    } 

}; 

return { 
    templateUrl: 'App_Data/Directives/Something/Something.html', 
    scope: {}, //Scope is now isolated! 
    controller: controller 
} 
}); 

您还可以添加变量通过在你的指令属性被注入到你的范围。

HTML

<my-directive lines="parentScopeVariable.lineCount"></my-directive> 

JS

'use strict'; 

angular 
    .module('myModule') 
    .directive('myDirective', 
    ['$rootScope', function ($rootScope) { 

    return { 
     restrict: 'E', 
     scope: 
     { 
     lines: '=lines' 
     }, 
     templateUrl: 'views/templates/my-directive.html', 
     link: function ($scope, element, attributes, controller) {}, 
     controller: function ($scope) 
     { 
     //Lines is equal to whatever value the variable outside 
     //the scope had, and uses two-way binding like you 
     //would expect 
     console.log ($scope.lines); 
     } 
    }]); 

补充阅读:Understanding ScopeMastering the Scope of the Directives in AngularJS,任何数量的其他博客文章或文章,以这种效果的。

有很多这方面的资源。不要害怕继续寻找,直到你找到一个真正引起你的学习风格的共鸣。就我而言,阅读文档就像是将我的头撞在墙上,但是在阅读我发现的随机博客文章时,指令开始有意义,同时寻找不同问题的答案。

与指令

尝试手动注入范围到控制器:

controller.$inject = ['$scope']; 

使用controllerAs语法来避免范围的问题,如您有以上:

 angular.module('your_module').directive('someDirective', someDirective); 

     function someDirective(){ 
        var directive = { 
        templateUrl: 'App_Data/Directives/Something/Something.html', 
        controller: ExampleController, 
        controllerAs: 'vm', 
        bindToController: true}; 

        return directive; 
        } 


     function ExampleController() { 
      var vm = this; 
      vm.data = ''; 
     } 

这将有助于一吨与使它更容易外部范围绑定到该指令的控制范围

而且通过将bindToController设置为true,它将帮助您将外部范围绑定到指令的控制器的作用域