0

ユーザーが範囲内の値を選択できるようにする派手なスライダーを作成しており、それを AngularJS ディレクティブとして構築しようとしています。範囲内の各ステップには、その位置に表示される簡単なテキスト説明があります。例えば:

 Temperature
                  Warm
[------------------^------]
 |     |     |     |     |
 Cold                  Hot

この初期マークアップをページで使用したいと思います。これはセマンティックであり、適切に劣化するためです。

<div class="prompt scale">
    <label for="mySelect">Temperature</label>
    <select name="mySelect">
        <option value="1">Cold</option>
        <option value="2">Cool</option>
        <option value="3">Neutral</option>
        <option value="4">Warm</option>
        <option value="5">Hot</option>
    </select>
</div>

次に、これを派手なスライダーのマークアップに完全に置き換えます。ただし、これを行うには、派手なスライダーをレンダリングするために必要なデータ (各オプションの値とラベル) を抽出するために、Angular が元のマークアップを読み取ることができる必要があります。ただし、元の要素とその子への参照を取得できる場所が見つかりません。ディレクティブを宣言するとき、compile() および link() 関数は両方とも、オリジナルではなくテンプレート要素を参照します。子孫へのアクセスを含め、元のマークアップを読み取るにはどうすればよいですか?

4

1 に答える 1

2

ディレクティブ構成オブジェクトでテンプレート プロパティを使用する場合は、オリジナルを表示できなくなると思います。

あなたがしていることを効果的に行うには、私がよく理解していない compile ディレクティブ関数を使用する必要があると思います.これを示すためにそれを使用せずに逃げました:

http://jsfiddle.net/2TPWA/

基本的に、重要なデータごとにディレクティブを作成します。これらすべてのデータを登録するためにコントローラーを共有してもらいます。このようにすることで、親ディレクティブは、必ずしも指定された深さでなくても、その子を持つことができます。元のマークアップを非表示 (または必要に応じて削除) し、統合された情報に基づいてウィジェットを作成します。

あなたの場合、ここで見たようにすべてを配線するためのディレクティブと、それ自体がウィジェットになる別のディレクティブを作成し、別の回答者が提案したような属性または構成オブジェクトで作成できます。

<div>
<div sliding-scale class="prompt scale">
<label sliding-scale-title for="mySelect">Temperature</label>
<select name="mySelect">
    <option sliding-scale-option value="1">Cold</option>
    <option sliding-scale-option value="2">Cool</option>
    <option sliding-scale-option value="3">Neutral</option>
    <option sliding-scale-option value="4">Warm</option>
    <option sliding-scale-option value="5">Hot</option>
</select>
</div>
</div>



var myApp = angular.module('myApp', []);

myApp.directive('slidingScaleTitle', function () {
    return {
        require: '^slidingScale',
        link: function (scope, element, attrs, controller) {
            controller.setTitle(element.text());
        }
    };
});

myApp.directive('slidingScaleOption', function () {
    return {
        require: '^slidingScale',
        link: function (scope, element, attrs, controller) {
            controller.addOption({ 
                value: attrs.value,
                text: element.text()
            });
        }
    };
});

myApp.directive('slidingScale', function ($compile) {
    var template = '<div><b>{{ title }}</b><ul><li ng-repeat="o in options"><b>{{ o.value }}:</b> {{ o.text }} </li></ul>';

    return {
        // You should make this its own controller if you want this unit-tested.
        // I'm inlining it as an example.
        controller: function ($scope) {
            var title;
            var options = [];

            this.setTitle = function (value) {
                title = value;
            };
            this.getTitle = function () {
                return title;
            };
            this.getOptions = function () {
                return options;
            }
            this.addOption = function (value) {
                options.push(value);
            };
        },
        link: function (scope, element, attrs, controller) {

            scope.$watch(controller.getTitle, function (value) {
                scope.title = value;
            });

            scope.$watch(controller.getOptions, function (value) {
                scope.options = value;
            });

            element.children().css('display', 'none');
            fancySliderElement = angular.element(template);
            element.append(fancySliderElement);
            $compile(fancySliderElement)(scope);
        }
    }
});
于 2013-08-29T07:22:23.033 に答える