Почему мои ограничения на использование AngularJS?

Я попытался создать простую директиву, которая отображает имя и позволяет ему изменять. Когда я помещаю несколько директив на страницу имен, все они, похоже, используют атрибут name. Что я делаю неправильно?

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

Ответ 1

Как упоминалось в предыдущих ответах, поведение директив AngularJS по умолчанию заключается в совместном использовании области, в которую они включены. Такое поведение изменяется с помощью параметра scope в объекте определения директивы.

Вы можете просмотреть документацию для аргумента scope в этом разделе документов AngularJS: http://docs.angularjs.org/api/ng.$compile#description_comprehensive-directive -api_directive-определение-объект

Этот аргумент имеет три варианта:

  • scope: false - поведение по умолчанию для совместного использования области действия директивы включено в

  • scope: true - создайте новую область действия директивы, которая действует как другие дочерние области и прототипически наследует ее родительскую область

  • scope: {} - создать изолированную область действия, которая не прототипически наследуется от родительской области

Как вы можете видеть в примерах JSBin, оба варианта 2 и 3 будут работать для вашего примера. Разница заключается в том, хотите ли вы, чтобы ваши новые области были изолированы или нет.

В разделе директив руководства AngularJS есть хороший раздел о том, почему изолированная область может помочь создать более совершенные модули повторного использования с директивами: Руководство AngularJS: выделение области действия директивы

Ответ 2

По умолчанию, если вы не изолируете область действия директивы, вы поделитесь "внешней" областью со всеми экземплярами вашей индивидуальной директивы. С вашей текущей реализацией вам нужно каждый раз создавать разные контроллеры, чтобы повторно использовать такую ​​директиву.

НО есть решение этого недостатка, и оно называется областью выделения. Для этого вы можете использовать параметр области действия, например:

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,
}

У вас есть полный пример и объяснение здесь раздел Изоляция области действия директивы

Ответ 3

По умолчанию директивы используют одну и ту же область. Но при необходимости вы можете использовать изолированную область действия для своих директив: используйте поле 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,
    }

  });

Ответ 4

У вас есть 3 варианта scope в директивах AngularJS

  • false (использует родительскую область)
  • true (создает собственную область, а также наследует от родителя, то есть вы можете обращаться к элементам, определенным в родительской области)
  • {} (создает изолированную область)

Параметры области действия 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
    };

Проверьте живую демонстрацию