具有2个输入滑块的自定义指令

时间:2015-12-22 18:12:13

标签: angularjs angularjs-directive

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

我有这个简单的程序运行良好,我想将它重构为自定义指令。我希望指令元素是div标签的子body。我无法想象滑块值如何在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>

1 个答案:

答案 0 :(得分:2)

当你写下“如何将滑块值从输入标签向上传递到div以及相反的方式”时,我认为你意味着在指令和控制器之间共享数据。

绑定可能是角度的最佳用法,您可以在此处实现。将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>