如何从任何一个指令更改所有指令范围值?

时间:2016-10-31 12:06:19

标签: angularjs angularjs-scope angular-directive

我有一个重复n次的指令。我在每个指令中都有click事件动作。每当我点击click单击函数时,它就会改变一些在指令中定义的范围变量名。但它不会改变所有其他指令?怎么做到这一点?我有我的傻瓜。example

HTML:

  <!doctype html>
<html ng-app="myApp" >
<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>
  <script>document.write('<base href="' + document.location + '" />');</script>
  <link rel="stylesheet" href="style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>
  <script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
  this is 1st time: <div sampledirective></div>
  <br />
  this is 2nd time: <div sampledirective></div>
  <br />
  this is 3th time: <div sampledirective></div>
  <br />
  this is 4th time: <div sampledirective></div>
  <br />
  this is 5th time: <div sampledirective></div>
</body>
</html>

在我看来,我已经将'samplingirective'渲染了5次。

控制器:

  app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.bar ="original bar";
  $scope.term = "original term"
  $scope.temp={};
  $scope.callMethod = function (){
    $scope.term = "Changed term"
    $scope.bar = "Changed bar";
    $scope.temp.callMethod();
  }

});

我在控制器中创建了一个对象'temp'。

指令:

app.directive('sampledirective', function($http) {
  return {
      restrict: 'A',
      scope:true,
       replace: true,
       link:function(s,e,a){
         s.directive_scope="original directive_scope value";
         s.temp.callMethod = function(){

            s.directive_scope="Changed directive_scope value";
         }

       },
       template: '<div ><a ng-click="callMethod()">click_here</a> <span> <b>{{bar}}</b></span>   <span> <b>{{term}}</b></span>  <span> <b>{{directive_scope}}</b></span></div>'
  }

});

在我的指令模板中,我有'temp.callMethod()',它改变了范围变量值'directive_scope = Changed directive_scope value'。但它没有反映在其他指令中。怎么做到这一点?

1 个答案:

答案 0 :(得分:2)

问题

仔细查看您的指令定义,注意您将scope:true放在那里。

它的作用是告诉Angular为这个从父节点继承它的指令的特定实例创建一个新的隔离范围。

因此,您将遇到5个指令实例,这些实例都有自己的作用域,当您在其中一个指定其中之一时,它将不会反映在其他指令中。您可以阅读有关指令及其范围的更多信息here

解决方案1 ​​

您应该在父作用域中定义属性,然后使用双向绑定将其传递给指令

控制器定义

app.controller('MainCtrl', ['$scope', function ($scope) {
    $scope.directiveScope = null;
    $scope.temp = {};
    $scope.callMethod = function () {
        $scope.term = "Changed term"
        $scope.bar = "Changed bar";
        $scope.temp.callMethod();
    };
}]);

指令定义

app.directive('sampleDirective', function () {
    return {
        ...
        scope: {
            temp: '=',
            callMethod: '&',
            directiveScope: '=' 
        },
        ...
    };
});

HTML

<div sample-directive temp="temp" call-method="callMethod()" directive-scope="directiveScope"></div>

请注意每个指令实例都会将自己的temp.callMethod函数写入父作用域的temp属性。

解决方案2

您应该定义一个服务,该服务将存储共享值并将其注入控制器和指令

服务定义

app.factory('sharedData', function () {
    return {
        directiveScope: null
    };
});

控制器定义

app.controller('MainCtrl', ['$scope', 'sharedData', function ($scope, sharedData) {
    ...
    $scope.callMethod = function () {
        $scope.term = "Changed term"
        $scope.bar = "Changed bar";
        sharedData.directiveScope = "Changed directive_scope value";
    }
}]);

指令定义

app.directive('sampleDirective', ['sharedData', function (sharedData) {
    return {
        scope: {
            callMethod: '='
        },
        link: function ($scope, $element) {
            $scope.sharedData = sharedData;
        },
        template: '<div><a ng-click="callMethod()">click_here</a> <span> <b>{{bar}}</b></span>   <span> <b>{{term}}</b></span>  <span> <b>{{sharedData.directiveScope}}</b></span></div>'
    };
}]);

注意我将模板中的输出更改为{{sharedData.directiveScope}}