【问题标题】:Custom directive with 2 input sliders带有 2 个输入滑块的自定义指令
【发布时间】:2016-03-29 01:57:49
【问题描述】:

我正在学习如何在 AngularJS 中制作自定义指令。

我有一个运行良好的简单程序,我想将它重构为自定义指令。我希望指令元素是div,它是body 标签的子元素。我无法想象滑块值将如何在 DOM 中从 input 标记向上和向下传递到 div,反之亦然。

代码:

<html ng-app="DualSlidersApp">
<head>
  <meta charset="UTF-8">
  <title>DualSlidersApp</title>
  <style>
    .indented { margin-left: 61px; }
  </style>
  <script src="js/angular.js"></script>
  <script>
    'use strict';
    var app = angular.module('DualSlidersApp', []);
    app.controller('DualSlidersController', ['$scope', function($scope) {
      $scope.firstRangeSliderValue  = 10;
      $scope.secondRangeSliderValue = 20;
      $scope.reconcileSliders = function reconcileSliders(drivenByWhichSlider) {
        if ($scope.firstRangeSliderValue > $scope.secondRangeSliderValue) {
          if (drivenByWhichSlider === 'drivenByTheFirstSlider') {
            $scope.secondRangeSliderValue = $scope.firstRangeSliderValue;
          } else {
            $scope.firstRangeSliderValue = $scope.secondRangeSliderValue;
          }
        }
      }
    }]);
  </script>
</head>
<body ng-controller="DualSlidersController">
<div>
  <table>
    <tr>
      <td>
        <input type="range" min="10" max="30" step="2"
               ng-model="firstRangeSliderValue"
               ng-change="reconcileSliders('drivenByTheFirstSlider');">
      </td>
      <td>{{ firstRangeSliderValue }}</td>
    </tr>
    <tr>
      <td>
        <input type="range" min="20" max="40" step="2" class="indented"
               ng-model="secondRangeSliderValue"
               ng-change="reconcileSliders('drivenByTheSecondSlider');">
      </td>
      <td>{{ secondRangeSliderValue }}</td>
    </tr>
  </table>
</div>
</body>
</html>

【问题讨论】:

  • 您说您希望 div 成为指令,并且输入字段在该 div 内,那么“滑块值如何在 DOM 中上下传递”是什么意思div的输入标签和其他方式“?您的意思是如何将值传递给控制器​​,反之亦然?
  • @Someonation 我的假设是,当我在 div 上定义链接函数时,我需要将小部件整体的两个有趣值作为 div 包装器的属性,但是它们属于div 深处的 HTML 标签,那么我如何在 div 级别“符号链接”它们(因为缺乏更好的术语)。
  • 您的意思是,例如,在 div 包装器中提供“10”作为属性并将第一个 div 的 min 属性设置为 10?

标签: angularjs angularjs-directive


【解决方案1】:

当您编写“滑块值如何在 DOM 中从输入标签向上和向下传递到 div 以及反之亦然”时,我假设您的意思是在指令和控制器之间共享数据。

绑定可能是您可以在此处实现的 Angular 的最佳用途。将控制器范围内的 2 个变量绑定到指令范围内,每个变量代表每个滑块的值。我还建议将一个函数也传递给指令的范围,因此 ng-change 将在控制器中被回调。它应该看起来像这样:

directive.js

app.directive('dualSlidersDirective', function() {
  return {
    scope: {
      sliderOneValue: '=',
      sliderTwoValue: '=',
      onSliderChange: '&'
    },
    templateUrl: 'directive.html'
  };
});

directive.html:

<div>
  <table>
    <tr>
      <td>
        <input type="range" min="10" max="30" step="2"
               ng-model="sliderOneValue"
               ng-change="onSliderChange({drivenByWhichSlider: \'drivenByTheFirstSlider\'})">
      </td>
      <td>{{ sliderOneValue }}</td>
    </tr>
    <tr>
      <td>
        <input type="range" min="20" max="40" step="2" class="indented"
               ng-model="sliderTwoValue"
               ng-change="onSliderChange({drivenByWhichSlider: \'drivenByTheSecondSlider\'})">
      </td>
      <td>{{ sliderTwoValue }}</td>
    </tr>
  </table>
</div>

不要忘记在主 html 中绑定控制器范围内的相关变量和函数,注意函数接收它们的参数作为哈希(键是参数的名称,值是它的值)。在整个脚本中保持相同的变量名称非常重要

所以整个事情应该是这样的:

<html ng-app="DualSlidersApp">
<head>
  <meta charset="UTF-8">
  <title>DualSlidersApp</title>
  <style>
    .indented { margin-left: 61px; }
  </style>
  <script src="js/angular.js"></script>
  <script>
    'use strict';
    var app = angular.module('DualSlidersApp', []);
    app.controller('DualSlidersController', ['$scope', function($scope) {
      $scope.firstRangeSliderValue  = 10;
      $scope.secondRangeSliderValue = 20;
      $scope.reconcileSliders = function reconcileSliders(drivenByWhichSlider) {
        if ($scope.firstRangeSliderValue > $scope.secondRangeSliderValue) {
          if (drivenByWhichSlider === 'drivenByTheFirstSlider') {
            $scope.secondRangeSliderValue = $scope.firstRangeSliderValue;
          } else {
            $scope.firstRangeSliderValue = $scope.secondRangeSliderValue;
          }
        }
      }
    }]);
    app.directive('dualSlidersDirective', function() {
      return {
        scope: {
          sliderOneValue: '=',
          sliderTwoValue: '=',
          onSliderChange: '&'
        },
        template:             
            '<div>' +
              '<table>' +
                '<tr>' +
                  '<td>' +
                    '<input type="range" min="10" max="30" step="2"' +
                           'ng-model="sliderOneValue"' +
                           'ng-change="onSliderChange({drivenByWhichSlider: \'drivenByTheFirstSlider\'})">' +
                  '</td>' +
                  '<td>{{ sliderOneValue }}</td>' +
                '</tr>' +
                '<tr>' +
                  '<td>' +
                    '<input type="range" min="20" max="40" step="2" class="indented"' +
                           'ng-model="sliderTwoValue"' +
                           'ng-change="onSliderChange({drivenByWhichSlider: \'drivenByTheSecondSlider\'})">' +
                  '</td>' +
                  '<td>{{ sliderTwoValue }}</td>' +
                '</tr>' +
              '</table>' +
            '</div>'
      };
    });
  </script>
</head>
<body ng-controller='DualSlidersController'>
  <dual-sliders-directive slider-one-value='firstRangeSliderValue' slider-two-value='secondRangeSliderValue' on-slider-change='reconcileSliders(drivenByWhichSlider)'></dual-sliders-directive>
</body>
</html>

【讨论】:

    猜你喜欢
    • 2020-09-01
    • 1970-01-01
    • 2014-08-28
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 2017-06-06
    • 2022-11-21
    • 2017-10-14
    相关资源
    最近更新 更多