2

作为练习,我正在使用 RGB 和十六进制创建颜色值的输入。

html:

<form ng-controller="myCtrl">
    R:<input ng-model="rChannel" type="number" min="0" max="255" required></input>
    G:<input ng-model="gChannel" type="number" min="0" max="255" required></input>
    B:<input ng-model="bChannel" type="number" min="0" max="255" required></input>

    hex: #<input ng-model="hexColor" type="text" required></input>
</form>

js:

function myCtrl($scope) {
    $scope.$watch('[rChannel, gChannel, bChannel]',
              function() {
                $scope.hexColor = rgbToHex($scope.rChannel, $scope.gChannel, $scope.bChannel)
              },
              true);

    $scope.$watch('hexColor',
              function() {
                var rgbArr = hexToRgbArray($scope.hexColor);
                $scope.rChannel =  rgbArr[0];
                $scope.gChannel =  rgbArr[1];
                $scope.bChannel =  rgbArr[2];
              });
}

http://jsfiddle.net/F545z/

它起作用了……有一个大问题。一旦任何一个输入值变为无效(空字符串,或十六进制少于六个字符),所有输入都会消失!这具有删除用户已经输入的值的效果。例如,当用户键入一个有效的 6 个字符的十六进制值,然后按删除键更正十六进制的最后一个字符时,整个十六进制值就消失了,需要完全重新键入。如果您在控制台中观看,您可以看到正在发生的事情。我认为当十六进制无效时 rgb 输入消失是正确的行为,但它显然会妨碍用户擦除他/她在输入过程中的值。

这显然是由于“双重绑定”而发生的——rgb 和 hex 值正在监视它们自己的模型,但也相互监视。这里有一些严重的无限循环潜力,它可能只是工作,因为角度文档说循环只运行 10 倍以防止无限循环死锁。

我很确定我一开始就做错了。我应该尝试为十六进制输入编写单独的指令吗?如果是这样,我应该如何将它们全部链接起来?$watch 是否适合这种用途?一个工作小提琴是最有帮助的。

4

1 回答 1

5

$watch 适用于单向依赖。您希望根据用户输入的内容触发依赖关系。为此,在输入上使用 ng-change:

http://jsfiddle.net/F545z/1/

<div ng-app>
    <form ng-controller="myCtrl" novalidate>
        R:<input ng-model="redChannel" ng-change="updateHex()" type="number"  min="0" max="255" required></input>
        G:<input ng-model="greenChannel" ng-change="updateHex()" type="number"  min="0" max="255" required></input>
        B:<input ng-model="blueChannel" ng-change="updateHex()" type="number"  min="0" max="255" required></input>
        <br><br>
        hex: #<input ng-model="hexColor" ng-change="updateChannels()" type="text" required></input>
    </form>
</div>
于 2013-07-03T23:56:44.730 回答