2013-11-04 107 views
15

我試圖做一個簡單的指令,顯示一個名稱,並允許它改變。當我在名稱頁面上放置多個指令時,它們似乎都共享名稱屬性。我究竟做錯了什麼?爲什麼我的AngularJS指令共享範圍?

<!DOCTYPE html> 
<html ng-app="app"> 
<head> 
<meta charset=utf-8 /> 
<title></title> 

    <script src="http://code.angularjs.org/1.2.0-rc.3/angular.min.js"></script> 
    <script src="http://code.angularjs.org/1.2.0-rc.3/angular-resource.min.js"></script> 
    <script src="http://code.angularjs.org/1.2.0-rc.3/angular-animate.min.js"></script> 
    <script> 
    var app = angular.module('app', []); 

    app.directive('person', function() { 

    function link ($scope, elem, attrs, ctrl) {  

     $scope.name = "OLD"   

     $scope.setName = function() { 
      $scope.name = 'NEW'; 
     } 
    } 

    return { 
     restrict: 'E', 
     replace: true, 
     template: "<span>Current name = {{name}}<a href='' class='btn' ng-click='setName()'>Change name</a><br></span>", 
     link : link, 
    } 

    }); 

    app.controller('MainCtrl', function ($scope) { }); 

    </script>  

</head> 

<body ng-controller='MainCtrl'> 
    <person></person><br> 
    <person></person><br> 
    <person></person><br> 
    <person></person><br> 
</body> 

</html> 
+0

你的所有指令共享相同的範圍的情況下,因爲它們不要使用隔離的範圍。簽出[指令文檔](http://docs.angularjs.org/guide/directive),「隔離指令的範圍」段落 –

回答

32

如前面提到的答案,AngularJS指令的默認行爲是分享他們包括在範圍之內。這種行爲是通過該指令定義對象的scope參數改變。

您可以在AngularJS文件的這一部分查看範圍參數文件:http://docs.angularjs.org/api/ng.$compile#description_comprehensive-directive-api_directive-definition-object

這種說法有三個選項:

  1. scope: false - 共享的範圍該指令的默認行爲包含在

  2. scope: true - 爲該指令創建一個新的作用域,其行爲與其他子作用域相似,並且從其父級原型繼承範圍

  3. scope: {} - 創建一個孤立的範圍不prototypically從其父繼承範圍

正如你可以看到JSBin的例子,選項2和3都適用於你的例子。不同之處在於您是否希望新的示波器分離。

的AngularJS指南的指示部分對爲什麼孤立的範圍可以幫助指令,創造出更好的可重複使用的模塊,一個好的部分:AngularJS Guide: Isolating the Scope of a Directive

3

默認情況下,如果您不隔離指令的範圍,您將與您的人員指令的所有實例共享「外部」範圍。使用您當前的實現,您需要每次創建一個不同的控制器以重新使用這樣的指令。

但有一個解決這個缺陷,它被稱爲隔離範圍。要做到這一點,你可以用一個指令的作用域選項,如下所示:

return { 
    restrict: 'E', 
    replace: true, 
    scope : {}, // this is where the magic happens 
    template: "<span>Current name = {{name}}<a href='' class='btn' ng-click='setName()'>Change name</a><br></span>", 
    link : link, 
} 

你有超過here部分一個完整的示例和explenation隔離一個指令

2

默認的範圍,指令共享相同的範圍。但如果需要,您可以使用隔離範圍作爲您的指令:在指令定義中使用scope: {}作爲字段。

app.directive('person', function() { 

    function link ($scope, elem, attrs, ctrl) {  

     $scope.name = "OLD"   

     $scope.setName = function() { 
      $scope.name = 'NEW'; 
     } 
    } 

    return { 
     restrict: 'E', 
     scope: {} 
     replace: true, 
     template: "<span>Current name = {{name}}<a href='' class='btn' ng-click='setName()'>Change name</a><br></span>", 
     link : link, 
    } 

    }); 
1

你有AngularJS指令

  1. falsescope 3個選項(使用父範圍)
  2. true(創建自己的範圍,也從父類繼承,即您可以訪問父範圍中定義的項目)
  3. {}(創建一個孤立的範圍)

AngularJS Directives scope option

讓我證明這一點使用$ rootScope

app.run(function($rootScope){ 
     $rootScope.firstname = "Root scope name"; 
     $rootScope.rootValue = "Root value"; 
    }); 

    app.directive("sampleDirective",function(){ 
     return{ 
     template:"<div>{{firstname}}{{rootValue}}</div>", 
// here rootValue will be accessible as its inherited from parent. You can overwrite this as well 
     scope : true, 
     controller:['$scope',sampleDirectiveScope] 
     }; 
    }); 

    function sampleDirectiveScope($scope){ 
     $scope.firstname = "child scope changing name - "; 
    }; 

    app.directive("isolatedScopeDirective",function(){ 
     return { 
     controller:isolatedFunction, 
     template:" this has isolated scope ,<div>{{rootValue}}</div>", 
    // here rootValue will not be accessible because it is isolated and not inheriting from parent 
     scope: {} 
     }; 
    }); 

    function isolatedFunction($scope){ 
     //define values for this scope 
    }; 

入住這live demo