0

データ テーブルに単純な強調表示メカニズムを設定しようとしています。

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Owner</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="file in files" highlightable> <!-- Multiple instances of highlightable -->
            <td>{{file.name}}</td>
            <td>{{file.owner}}</td>
        </tr>
    </tbody>
</table>

そして、強調表示を処理するディレクティブがあります。をクリックする<tr>と、最初に他のすべての のハイ<tr>ライトが解除され、次にクリックされた がハイライトされます。

directive('highlightable', function() {
    return {
        require: 'highlightable',
        controller: function($scope, $element) {
            this.unhighlight = function(file) {
                $element[0].style.backgroundColor = 'transparent';
            };
        },
        link: function(scope, element, attrs, ctrl) {
            var color = '#DEE4FC';
            element.bind('click', function(e) {
                ctrl.unhighlight(scope.file);
                element[0].style.backgroundColor = color;
            });
        }
    };
});

問題は、ディレクティブのコントローラーのすべてのインスタンスにアクセスしていないように見えることです。別のディレクティブを要求する場合、シナリオでそのディレクティブのすべてのインスタンスを要求し、ng-repeat繰り返されるディレクティブのコントローラー メソッドを介して各インスタンスを操作するにはどうすればよいですか?

http://jsfiddle.net/txBJ6/1/

4

3 に答える 3

1

あなたが達成しようとしていることを考えると、私はこれをします。基本的にスコープ通知を使用して要素間で通信します。

directive('highlightable', function() {
    return {
        link: function(scope, element, attrs) {
            var color = '#DEE4FC';
            scope.$on("reset", function() {
                element[0].style.backgroundColor = 'transparent';
            });
            element.bind('click', function(e) {
                scope.$parent.$broadcast("reset");
                element[0].style.backgroundColor = color;
            });
        }
    };
});

デモ:リンク

更新され
た sze は、私のソリューションは、リストが 1 つだけ必要な場合にのみ適していることを正しく指摘しています (これは、質問の場合のようです)。ただし、コードの簡潔さを維持しながら、複数のリストに対応することは非常に簡単です。

<tr ng-repeat="file in files" highlightable="list1">
    <td>{{file.name}}</td>
    <td>{{file.owner}}</td>
</tr>

...

<tr ng-repeat="file in files" highlightable="list2">
    <td>{{file.name}}</td>
    <td>{{file.owner}}</td>
</tr>

...

directive('highlightable', function () {
    return {
        link: function (scope, element, attrs) {
            var color = '#DEE4FC';
            scope.$on(attrs.highlightable, function () {
                element[0].style.backgroundColor = 'transparent';
            });
            element.bind('click', function (e) {
                scope.$parent.$broadcast(attrs.highlightable);
                element[0].style.backgroundColor = color;
            });
        }
    };
});

デモ:リンク

于 2013-08-29T22:18:50.870 に答える
1

[@buu Nyuyen] のアプローチの問題は、彼がスコープを処理するためのいくつかのロジックを見逃していることです。ディレクティブによって変更された別のリストhighlightableがある場合、最初のリストからイベントがブロードキャストされ、ディレクティブが再利用できなくなると、2 番目のリストが影響を受けます。この問題はこちらで確認できます。Issue

ただし、他の要素をループすることで簡単に実現できます。トリックは、繰り返されるすべての要素を で取得できることですelement[0].parentElement.children

directive('highlightable', function () {
    return {
        require: 'highlightable',
        controller: function ($scope, $element) {
            this.unhighlight = function (element) {
                element.style.backgroundColor = 'transparent';
            };
        },
        link: function (scope, element, attrs, ctrl) {
            var color = '#DEE4FC';
            element.bind('click', function (e) {
                angular.forEach(element[0].parentElement.children, function (element) {
                    ctrl.unhighlight(element);
                })
                element[0].style.backgroundColor = color;
            });
        }
    };
});

Working Demo

于 2013-08-30T00:34:03.343 に答える
0

最も簡単な解決策は、Buu Nguyen によって提案されたものです。私はより難しい解決策を提供します。

これを解決する典型的な方法の 1 つは、すべての子の知識を持つ親ディレクティブを用意することです。したがって、すべての行をそこに登録することができ、1 つをクリックすると、親は他の子の強調表示を解除します。

より複雑ですが、より構成可能です。... という名前の属性を作成して、multi複数を強調表示することができます。または、最大行数を選択することもできxます...あなたが望むもの。

興味があれば、デモをここに残しておきます: http://jsfiddle.net/5NSW3/1/

于 2013-08-29T22:29:35.197 に答える