2

サーバーをポーリングしてアイテムのリストを取得し、結果を表示するアプリがあります。ここにフィドルの例があります。

モデルが変更されたときにカスタムアニメーションが必要ですが、値が変更されたプロパティ、つまり例の Item2 に対してのみです。

  1. コントローラーがポーリングするたびに項目コレクション全体を置き換えていますが、変更された値のみで現在のリストを更新するにはどうすればよいですか? ループして比較する必要がありますか、それとももっと良い方法がありますか?

  2. この例は、スパン内のバインドされた値が値を変更するたびに起動する最良の方法ですか?

HTML:

<div ng-app="myApp">
    <div ng-controller='ItemCtrl'>
        <div ng-repeat="item in items">
            <div>{{item.Name}}</div>
            <div><span>Item1: </span><span animate ng-model="item.Item1"></span></div>
            <div><span>Item2: </span><span animate ng-model="item.Item2"></span></div>
        <div><br>
    </div>
</div>

JS:

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

    myApp.controller("ItemCtrl", 
        ['$scope', '$timeout', 'getItems1', 'getItems2',
            function ($scope, $timeout, getItems1, getItems2) {

        $scope.items = [];

        var change = false;

        (function tick() {
            bindItems();
            $timeout(tick, 2000);
        })();

        function bindItems() {
            if (change) {
                $scope.items = getItems2;
            }
            else if (!change){
                $scope.items = getItems1;
            }

            change = !change;
        }
    }]);

    myApp.factory('getItems1', function() {

        return [ 
            {
                Name: 'foo1',
                Item1: 1,
                Item2: 2
            },
            {
                Name: 'foo2',
                Item1: 3,
                Item2: 4
            },
        ];

    });

    myApp.factory('getItems2', function() {

        return [ 
            {
                Name: 'foo1',
                Item1: 1,
                Item2: 6
            },
            {
                Name: 'foo2',
                Item1: 3,
                Item2: 8
            },
        ];

    });

    myApp.directive('animate', function(){

    // Some custom animation when the item within this span changes

    return {
        require: 'ngModel',
        link: function(scope, elem, attrs, ngModel) {
            scope.$watch(function() {
                return ngModel.$modelValue;
            }, function (newValue, oldValue, other) {
                var $elem = $(elem);

                console.log(newValue + ' ' + oldValue + ' ' + other);
                // I don't want to animate if the values are the same, but here
                // oldValue and newValue are the same, because I'm replacing the 
                // entire items list??
                //if (newValue === oldValue)
                //{
                //    $elem.html(newValue);
                //} else
                {
                // oldValue same as newValue, because I'm replacing the entire items
                // list??
                    $elem.html(oldValue);
                    $elem.slideUp(1000, function() {
                        $elem.html(newValue);
                    }).slideDown(1000);
                }
            });
    }
};

    })

アップデート:

リストをループしてプロパティを個別に更新することで、これが機能しました。jsfiddle

a) プロパティをループする必要がない、b) ウォッチの前後のイベントにフックできる、より良い方法があるはずだと感じていますが、.html() を使用して値を設定する必要はありません。

4

0 に答える 0