0

我正在尝试编写一个动画指令,它会改变元素的宽度并在模型后缀中做出改变。这是我的代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <div ng-app="myApp" ng-controller="MyCtrl">
            <button ng-init="speed=20000" ng-click="model.width = model.width + 100;"> + </button>
            <button ng-click="model.width = model.width - 100;"> - </button>
            <div animate-to-width="model.width" speed="{{speed}}" done="model.done()" style="background-color: #f00; width: 100px;">w:{{model.width}}|a:{{model.a}}|b:{{model.b}}</div>
        </div>

        <script src="components/jquery/jquery.js"></script>
        <script src="components/angular-unstable/angular.js"></script>
        <script>

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

myApp.directive('animateToWidth', function() {
    return {
        'restrict': 'A',
        'link' : {
            'post': function(scope, element, attrs) {
                scope.$watch(
                    attrs.animateToWidth,
                    function (newValue) {
                        element.animate(
                            {'width': newValue + 'px'},
                            attrs.speed,
                            function () {
                                scope.model.a++;
                                //scope[attrs.done]();
                            }
                        );
                    }
                );
            }
        }
    };
});

function MyCtrl($scope) {
    $scope.model = {};
    $scope.model.width = 100;
    $scope.model.a = 0;
    $scope.model.b = 0;
    $scope.model.done = function () { $scope.model.b++; };
}

        </script>
    </body>
</html>

当我运行此代码时,jQuery .animate() 函数的第二个参数似乎不会影响动画速度,并且会在动画完成后立即调用回调(第三个参数)。

我的第二个问题是,我想将一个回调从控制器传递到指令中,但我不知道如何实现这一点。

编辑

这是解决方案(感谢@banana-in-black):

http://plnkr.co/edit/D9TJHBYjtnxTve0xZpBS?p=preview

在控制器中没有这些宽度值:

http://plnkr.co/edit/eiy99Crh57Jc78RhAsRt?p=preview

4

1 回答 1

1

您从 attrs.speed 得到的是,如果您将持续时间设置为,String则没有效果。因此,将其设为数字​​可以解决速度问题。StringjQuery.animate()

之后的回调在jQuery.animate()“角度世界”之外调用,因此您必须使用$apply来确保角度知道模型发生了什么。

如果您没有为指令分配范围,它将使用元素上的现有范围。在这种情况下, div[animate-to-width] 使用与 MyCtrl 相同的范围。您可以只调用在控制器中设置为范围的函数。

scope.$watch(
    attrs.animateToWidth,
    function (newValue) {
        element.animate(
            {'width': newValue + 'px'},
            attrs.speed * 1,
            function () {
                scope.$apply(function() {
                    scope.model.a++;
                    scope.model.done();
                });
            }
        );
    }
);

Plunker 中的示例

于 2013-10-05T20:26:08.937 回答