【问题标题】:Different scope for multiple instances of Angular directiveAngular指令的多个实例的不同范围
【发布时间】:2016-03-31 18:28:50
【问题描述】:

我有以下 Angular 指令,它从父控制器的范围内获取数据。我的问题是,当同一指令多次添加到同一页面时,它们的范围变得相同。每当任何指令中的某个值发生更改时,所有指令中的相同值也会发生更改。

我的指令

angular.module('myapp').directive('memberAddress', function () {
    return {
        restrict: 'E',
        templateUrl: '/Directives/memberAddress.html'
    }
});

memberAddress.html:

  <div class="col-md-4">
     <h3>{{addressModel.title}}</h3>
  </div>

父设计:

<div id="addressDiv">
    <div class="row"></div>
</div>

父控制器:

angular.module('myapp').controller('MemberController', MemberController);
MemberController.$inject = ['$scope', '$compile'];

function MemberController($scope, $compile) {
     $scope.addressModel = { title: ''}
     $scope.addAddress = function () {
           // "$scope.addressModel" Now it has some title text from UI.
           var row = angular.element(document.getElementById('addressDiv')).find('.row');
           var el = $compile("<member-address></member-address>")($scope);
           row.append(el);
     }
}

在调用 addAddress() 时,它会第一次向页面添加一个“memberAddress”指令。但是当我从 UI 添加另一个 addressModel.title 时,它​​会添加一个新指令,但它会更改先前添加的“memberAddress”指令中的标题,使所有指令的标题文本相同。

有什么方法可以防止其他指令发生变化?

【问题讨论】:

  • 我很难理解您想要实现的目标。但可以肯定的是,您不应该在控制器中进行 DOM 操作。如果你想在页面中添加一个元素,那么在你的模型中添加一个对象到一个数组中,并使用 ng-repeat 来显示数组中的每个对象。

标签: angularjs angularjs-directive angularjs-scope


【解决方案1】:

在你的指令而不是你的控制器中设置你的范围。 angular js网站有一个例子。

.directive('myCustomer', function() { 
    return { 
        restrict: 'E',
        scope: { customerInfo: '=info' },
        templateUrl: 'my-customer-iso.html' 
    }; 
});

要使其与您的代码一起使用,您可能还必须将控制器重写为指令。

代码学校在他们的指令章节“用 Angular 塑造”中很好地介绍了这一点

【讨论】:

    【解决方案2】:

    尝试使用隔离作用域:

    angular.module('myapp').directive('memberAddress', function () {
        return {
            scope: {
                addressModel: "@"
            },
            restrict: 'E',
            templateUrl: '/Directives/memberAddress.html'
        }
    });
    

    memberAddress.html:

      <div class="col-md-4">
         <h3>{{addressModel().title}}</h3>
      </div>
    

    父设计:

    <div id="addressDiv">
        <div class="row">
            <member-address address-model="addressModel"></member-address>
        </div>
    </div>
    

    【讨论】:

      【解决方案3】:

      我通过为每个指令声明新范围来解决它。

      这里是父控制器的变化:

      angular.module('myapp').controller('MemberController', MemberController);
      MemberController.$inject = ['$scope', '$compile'];
      
      function MemberController($scope, $compile) {
          $scope.addressModel = { title: ''}
          $scope.addAddress = function () {
      
             // "$scope.addressModel" Now it has some title text from UI.   
      
             // UPDATE - Here I created a new scope.
             var addressDirectiveScope = $scope.$new(true);
             addressDirectiveScope.addressModel = $scope.addressModel;
      
             var row = angular.element(document.getElementById('addressDiv')).find('.row');
      
             //var el = $compile("<member-address></member-address>")($scope);          
             // UPDATE - Now I passed the new scope "addressDirectiveScope" instead of "$scope" to $compile.
             var el = $compile("<member-address></member-address>")(addressDirectiveScope);
             row.append(el);
          }
       }
      

      感谢大家的回答!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-13
        • 2014-12-01
        • 2017-01-17
        • 1970-01-01
        • 1970-01-01
        • 2016-04-30
        • 2015-10-25
        相关资源
        最近更新 更多