在指令作用域和控制器$scope之间共享数据

Share data between directive scope and controller $scope?

本文关键字:scope 之间 共享 数据 控制器 指令 作用域      更新时间:2023-09-26

这里我为日期选择器创建了一些示例,它运行良好,但我需要动态设置最小和最大日期。。所以我从开始和结束日期像这样的Html我的日期选择器min="2013-07-23"max="2015-07-23"在指令作用域中我得到了值,我需要在控制器$scope.datepickerOptions={startDate:min,endDate:max}中设置这个值。。

var app = angular.module('myapp', ['ng-bootstrap-datepicker'])
app.directive('myDatepicker', function() {
  return {
    restrict: 'E',
    template: '<input type="text" ng-datepicker ng-options="datepickerOptions"   ng-model="ngModel">',
    scope: {
      date: '=',
      ngModel: '=',
      min: '=',
      max: '=',
    },
    controller: function($scope) {
      $scope.datepickerOptions = {
        format: 'yyyy-mm-dd',
        autoclose: true,
        weekStart: 0,
        startDate :'2013-07-23',
        endDate:'2015-07-23'
      };
    }
  };
})
app.controller('AppCtrl', ['$scope', function ($scope) {
  $scope.date = '2013-08-12'
}]);
var appboot = angular.bootstrap(document, ['myapp']);
<link href="https://rawgit.com/cletourneau/angular-bootstrap-datepicker/master/dist/angular-bootstrap-datepicker.css" rel="stylesheet"/>
<link href="http://netdna.bootstrapcdn.com/bootstrap/2.0.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="http://code.jquery.com/jquery-2.0.2.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/2.0.4/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script src="https://rawgithub.com/cletourneau/angular-bootstrap-datepicker/master/dist/angular-bootstrap-datepicker.js" charset="utf-8"></script>
<body>
<div>
     <div ng-app="myapp" ng-controller="AppCtrl">
      <my-datepicker ng-model ="date"  min="2013-07-23"   max="2015-07-23"></my-datepicker>
     <input id="datepickerMirror" type="text"  data-ng-model="date">
</div>
</div>
</body>

$scope在指令控制器中IS与指令隔离的作用域。您可以从$scope.min和$scope.max.中获取值

Update 代码无法执行此操作的原因是您使用的是'='绑定,该绑定会导致指令在作用域中查找名为2013-07-23的变量。您需要将值放在变量中,或者将绑定更改为"@"并使用插值(大括号{{value}}),或者像min="'2013-07-23'" max="'2015-07-23'"中那样在双引号中用单引号将日期值括起来。

https://plnkr.co/edit/Gp5SBtIAuLq5BzzIdKfp?p=preview

var app = angular.module('myapp', ['ng-bootstrap-datepicker'])
app.directive('myDatepicker', function() {
  return {
    restrict: 'E',
    template: '<input type="text" ng-datepicker ng-options="datepickerOptions" ng-model="ngModel">',
    scope: {
      dateval: '=',
      ngModel: '=',
      min: '=',
      max: '=',
    },
    controller: function($scope) {
      $scope.datepickerOptions = {
        format: 'yyyy-mm-dd',
        autoclose: true,
        weekStart: 0,
        startDate : $scope.min,
        endDate: $scope.max
      };
    }
  };
})
app.controller('AppCtrl', ['$scope', function ($scope) {
  $scope.dateval = '2013-08-12';
  $scope.min = '2013-07-23';
  $scope.max = '2015-07-23';
}]);
var appboot = angular.bootstrap(document, ['myapp']);

html

<!DOCTYPE html>
<html>
  <head>
<link href="//rawgit.com/cletourneau/angular-bootstrap-datepicker/master/dist/angular-bootstrap-datepicker.css" rel="stylesheet"/>
<link href="//netdna.bootstrapcdn.com/bootstrap/2.0.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="//code.jquery.com/jquery-2.0.2.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/2.0.4/js/bootstrap.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script src="//rawgithub.com/cletourneau/angular-bootstrap-datepicker/master/dist/angular-bootstrap-datepicker.js" charset="utf-8"></script>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
  </head>

<body>
<div>
     <div ng-app="myapp" ng-controller="AppCtrl">
      <my-datepicker ng-model="dateval"  min="min" max="max"></my-datepicker>
     <input id="datepickerMirror" type="text"  data-ng-model="dateval">
</div>
</div>

</body>
</html>

如前一个答案的Updated注释中所述,它不适用于UPDATE的原因是您正在"绑定"(scope params with"=")到字符串文字。当您试图设置该变量时,可能还会遇到控制台错误,类似于对象"non-assign"。

话虽如此,你的指令需要一个孤立的范围是有原因的吗?如果您只是使用"scope:true"设置指令,那么您的指令将从父作用域原型继承。这降低了便携性,但在这一点上,你看起来并不是真的在为此而努力。

要设置有用的原型继承,您还需要在HTML视图文件中使用ng控制器的"as"语法。为了举例说明,我们假设:

ng-controller="AppCtrl as appCtl"

然后将datepickerOptions的初始化从指令移到主AppCtrl控制器中。就我个人而言,我更喜欢"点"语法,而不是在范围中乱丢难以跟踪的变量,所以把它分配给你的控制器,而不是范围:

this.datepickerOptions = { /* min, max, etc */ }

现在,在您的指令中(使用scope:true),您可以通过指令$scope访问该控制器。因此,在指令的控制器功能中:

$scope.datepickerOptions = $scope.appCtl.datepickerOptions

请注意,我在这里选择了"点"语法,因为否则原型继承将为指令中的datepickerOptions创建一个新的scope元素,而不是遍历和检查作用域链。通过使用点语法,访问上一个作用域变量(appCtl),然后子对象查找(datepickerOptions)使应用程序遍历作用域链并获取对象,而不是对其进行阴影处理。

最后一个要处理的部分是ngModel。如果到目前为止,您所要做的就是将ng模型(在指令模板中)设置为"appCtl.modelName",其中modelName是您要使用的变量。现在,您的控制器将直接为其分配该变量。如果您想在该值更改时执行某些操作,请将其添加到您的AppCtrl控制器中:

// create a variable so that it can be used in callbacks where "this" changes
var _this = this;
// Create this by hand since its ng-model binding is added dynamically by the directive template
_this.modelName = null;
$scope.$watch(function() { return _this.modelName; }, function(val, oldVal)
{
   // do something here, remembering that _this contains a reference to the controller itself
});

还要注意,在执行此操作时,您可以消除其他输入(datepickererror),因为您的所有数据都已在控制器中,并且只需由指令访问即可。

希望能有所帮助!