17

我试图制作一个简单的指令,它显示一个名称并允许它被更改。当我在名称页面上放置多个指令时,它们似乎都共享名称属性。我究竟做错了什么?

<!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>
4

4 回答 4

35

如前面的答案所述,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: {}- 创建一个在原型上不从其父范围继承的隔离范围

正如您在 JSBin 示例中看到的那样,选项 2 和 3 都适用于您的示例。不同之处在于您是否希望隔离新范围。

AngularJS 指南的指令部分有一个很好的部分,说明了为什么隔离范围可以帮助使用指令创建更好的可重用模块: AngularJS 指南:隔离指令的范围

于 2013-11-04T19:31:18.320 回答
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 section Isolating the Scope of a Directive

于 2013-11-04T19:05:36.227 回答
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,
    }

  });
于 2013-11-04T19:06:11.683 回答
1

scope在 AngularJS 指令中有 3 个选项

  1. false(使用父范围)
  2. true(创建自己的范围并从父范围继承,即您也可以访问在父范围中定义的项目)
  3. {}(创建一个孤立的范围)

AngularJS 指令范围选项

让我用 $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
    };

检查这个现场演示

于 2017-02-22T10:11:14.420 回答