2

演習として、RGB と 16 進数の両方を使用してカラー値の入力を作成しています。

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/

それはうまくいきます... 1つの大きな問題があります。1 つの入力値が無効になると (空の文字列、または 16 進数が 6 文字未満)、すべての入力が消えます! これには、ユーザーがすでに入力した値を削除する効果があります。たとえば、ユーザーが有効な 6 文字の 16 進数値を入力してから、Delete キーを押して 16 進数の最後の文字を修正すると、16 進数値全体が消えてしまい、完全に再入力する必要があります。コンソールで見ると、何が起こっているかがわかります。16進数が無効なときにrgb入力が消えるのは正しい動作だと思いますが、ユーザーが入力中の値を消去するのを明らかに妨げています。

これは明らかに「ダブル バインド」が原因で発生しています。RGB 値と 16 進値は、それぞれのモデルだけでなく、相互のモデルも監視しています。ここにはいくつかの深刻な無限ループの可能性があり、無限ループのデッドロックを防ぐためにループが 10 倍しか実行されないと角度のドキュメントに記載されているため、おそらくまったく機能していません。

そもそも私がこの間違った方法でやっていると確信しています。16 進入力用に別のディレクティブを作成する必要がありますか? もしそうなら、どのようにそれらをすべてリンクする必要がありますか? $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 に答える