0

以下のコードでは、私が呼び出しているという事実が$(".test").buttonset();の更新を中断してい{{ item.value() }}ます。jQuery UI が DOM を書き換えたことに関係があると思います。

<html ng-app>
    <head>
        <link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/start/jquery-ui.css" type="text/css" rel="Stylesheet" />
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.21/jquery-ui.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
        <script type="text/javascript">
            function ExampleCtrl($scope, $timeout) {
                $scope.list = [
                    { name: "a", value: 5 },
                    { name: "b", value: 6 },
                    { name: "c", value: 5 },
                    { name: "d", value: 6 }
                ];

                $scope.calc = [
                    [
                        {
                            name: "a, b avg",
                            value: function() { return(($scope.list[0].value + $scope.list[1].value) / 2) }
                        },
                        {
                            name: "c, d avg",
                            value: function() { return(($scope.list[2].value + $scope.list[3].value) / 2) }
                        }
                    ]
                ];

                $timeout(function() {
                    $(".test").buttonset();
                }, 0);
            }
        </script>
    </head>
    <body ng-controller="ExampleCtrl">
        <div class="test" ng-repeat="group in calc">
            <div ng-repeat="item in group">
                <input type="radio" name="a" id="{{item.name}}" />
                <label for="{{item.name}}">{{item.name}}: {{ item.value() }}</label>
            </div>
        </div>

        <ul ng-repeat="item in list">
            <li>{{item.name}}: <input type="number" ng-model="item.value" />
        </ul>
    </body>
</html>

ここに jsFiddle バージョンがあります: http://jsfiddle.net/vhLXW/

4

2 に答える 2

2

コントローラでのDom操作は良い考えではありません。あなたができるのは、buttonset()ジョブの実行を処理する単純なディレクティブを作成することです。それは次のようになります

directive('buttonset', function() {
    return function(scope, elm, attrs) {
      elm.buttonset();
    };
  });

そしてあなたのhtmlで、あなたはすることができます

<div class="test" ng-repeat="group in calc" buttonset>

これで、コードはhtml内のclass="test"の存在に依存しなくなりました。

あなたの状況で起こっていることは、JQueryUIがDOMを変換しているということです。ラジオボタンを非表示にし、他のhtml要素を配置します(ラジオグループのスタイルを変更します)。この新しいウィジェットがクリックされると、JQueryUIコードはそのクリックを対応するラジオボタンに伝播します。

JQuery UIがイベントまたは類似のものを公開した場合、それにフックして、Angularからを呼び出すことができます$scope.$apply();。しかし、残念ながら、そうではないようです(私が間違っていない限り)。

JQuery UIの外観が本当に必要な場合は、独自のコードを作成できます(JQuery UIがDOMを操作した後、HTMLの特定の部分をコピーして貼り付けます)。JQuery UIのスタイルを使用して、独自のロジックを記述します。Angularを使用すると、独自のロジックを非常に簡単に作成できます。

于 2012-08-13T15:04:02.650 に答える
1

jQuery UI で最初に DOM を変更し、次に AngularJS で DOM 操作を行います。このようにして、Angular は変更された DOM 要素にバインドします。JavaScript をページの下部に配置して、タイムアウトなしで機能するようにします。

</body>
<script type="text/javascript">
    $(".test").buttonset()  // allow jQuery UI to manipulate the DOM here, first!
    function ExampleCtrl($scope) {
        $scope.list = [ ... ];
        $scope.calc = [ [...] ];
    }
</script>

更新: @Chas.Owens が指摘したように、これは機能しません。データ バインディングは正しく機能しますが、UI が壊れています。(上記のように) jQuery UI が最初に DOM を変更すると、AngularJS のデータ バインディングは機能しますが、なぜか UI が壊れます。AngularJS が最初に DOM を変更すると (元の問題)、AngularJS のデータ バインディングは機能しませんが (おそらくボタンセットがラベルのテキストの周りに追加の <span> を追加するため)、UI は機能します。

于 2012-08-13T16:53:11.763 に答える