【问题标题】:two-way data binding inside attribute directive that requires element directive需要元素指令的属性指令内的双向数据绑定
【发布时间】:2015-11-06 17:08:49
【问题描述】:

我在同一个元素上有一个元素指令 (e-dir) 和一个属性指令 (a-dir):

<e-dir a-dir attr="msg"></e-dir>

我通过attr 属性将msg 传递到e-dir 的隔离范围:

app.directive('eDir', function eDir($timeout) {
  return {
    restrict: 'E',
    scope: {
      attr: '='
    }
  };
}); 

这样,msg$scope.attr(在EDirCtrl)或scope.attr(在e-dir 的链接函数中)绑定(双向)。

有没有一种简单的方法可以在a-dir 的指令中实现相同的双向数据绑定?或者您会推荐另一种更简单的方法吗?

我能想到的最接近的方法是将eDirCtrl.attr = $scope.attr; 设置在e-dir 的控制器(EDirCtrl)中:

app.directive('eDir', function eDir($timeout) {
  return {
    restrict: 'E',
    scope: {
      attr: '='
    },
    controller: function EDirCtrl($scope) {
      var eDirCtrl = this;
      eDirCtrl.attr = $scope.attr;
    },
    controllerAs: 'eDirCtrl'
  };
}); 

然后,让a-dir 要求e-dir,并通过e-dir 的控制器(eDirCtrl.attr)访问attr

app.directive('aDir', function aDir($timeout) {
  return {
    restrict: 'A',
    require: 'eDir',
    link: linkFn
  };

  function linkFn(scope, element, attrs, eDirCtrl) {
    eDirCtrl.attr = 'eDirCtrl.attr';
  }
});

但是,它不是双向绑定的。正如你所看到的这段代码sn-p:

var app = angular.module('app', []);

app.controller('Ctrl', function Ctrl($scope) {
  $scope.msg = 'initial message';
})

app.directive('eDir', function eDir($timeout) {
  return {
    restrict: 'E',
    scope: {
      attr: '='
    },
    template: '<div>$scope.attr: {{attr}}</div>'+
    '<div>eDirCtrl.attr: {{eDirCtrl.attr}}</div>',
    controller: function EDirCtrl($scope) {
      var eDirCtrl = this;
      eDirCtrl.attr = $scope.attr;
      $timeout(function() {
        $scope.attr = 'changing $scope.attr also changes msg';
      }, 2000);
    },
    controllerAs: 'eDirCtrl'
  };
}); 

app.directive('aDir', function aDir($timeout) {
  return {
    restrict: 'A',
    require: 'eDir',
    link: linkFn
  };

  function linkFn(scope, element, attrs, eDirCtrl) {
    $timeout(function() {
      eDirCtrl.attr = 'changing eDirCtrl.attr does not effect $scope.attr or msg';
    }, 4000);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="Ctrl">
  msg: <input type="text" ng-model="msg"><br>
  <e-dir a-dir attr="msg"></e-dir>
</div>

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    双向绑定不起作用的原因是attr 被绑定到字符串而不是对象。在 JavaScript 中,原语(布尔值、数字、字符串)是不可变的,因此当您更改一个时,前一个实例将被丢弃并使用一个新实例。这打破了 Angular 的双向绑定,对 scope.msg 的任何更改都不会通过 attr 传播到指令中。

    您可以通过在对象上设置msg 来使其按预期工作,例如scope.test.msg 并将 attr 绑定到 test(对象)而不是 msg(字符串)。

    我已经更新了你的代码 sn-p 来做到这一点:

    var app = angular.module('app', []);
    
    app.controller('Ctrl', function Ctrl($scope) {
      $scope.test = {msg : 'initial message'};
    })
    
    app.directive('eDir', function eDir($timeout) {
      return {
        restrict: 'E',
        scope: {
          attr: '='
        },
        template: '<div>$scope.attr: {{attr.msg}}</div>'+
        '<div>eDirCtrl.attr: {{eDirCtrl.attr.msg}}</div>',
        controller: function EDirCtrl($scope) {
          var eDirCtrl = this;
          eDirCtrl.attr = $scope.attr;
          $timeout(function() {
            $scope.attr.msg = 'changing $scope.attr also changes msg';
          }, 2000);
        },
        controllerAs: 'eDirCtrl'
      };
    }); 
    
    app.directive('aDir', function aDir($timeout) {
      return {
        restrict: 'A',
        require: 'eDir',
        link: linkFn
      };
    
      function linkFn(scope, element, attrs, eDirCtrl) {
        $timeout(function() {
          eDirCtrl.attr.msg = 'changing eDirCtrl.attr does not effect $scope.attr or msg';
        }, 4000);
      }
    });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    
    <div ng-app="app" ng-controller="Ctrl">
      msg: <input type="text" ng-model="test.msg"><br>
      <e-dir a-dir attr="test"></e-dir>
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 2015-03-07
      • 2018-04-22
      • 1970-01-01
      • 2013-06-15
      • 1970-01-01
      • 2015-02-01
      相关资源
      最近更新 更多