对指令中的每个功能执行默认操作

时间:2015-09-01 14:42:44

标签: javascript angularjs

我已经创建了一些具有某些功能的指令,如下所示:

myCtrl.directive('myDirective', function () {
    return {
        restrict: 'E',
        scope: {
            'something': '='
        },
        link: function (scope, el, attr) { 
             function func1(){
                 //some stuff
                 scope.$apply();
             }
             function func2(){
                 //some stuff
                 scope.$apply();
             }
             function func3(){
                 //some stuff
                 scope.$apply();
             }
             //...
        }
    }
});

我必须在所有函数中调用scope.$apply()来更新视图。另外,我不想在控制器中定义它们。我不知道是否有诀窍可以避免这种模式。它工作正常,但我认为这不是一个好的解决方案。

更新

我们为某些形状创建了超过10个指令,例如:矩形,圆形,方形等。在这些我称之为$apply的函数中,实现了拖拽和缩放等一些方法。所以我需要调用$apply来修改模型中的更改,从而更新视图。除非我在控制器中写下大约100个函数,否则我不知道如何让它们能够自动识别scope! 另外,我使用了一些第三方库,例如d3.js。像clicked这样的事件在调用这些函数时是有限的。

3 个答案:

答案 0 :(得分:3)

真正的事实是,只要您在角度消化周期之外改变某些内容,就需要拨打$scope.$apply()。 Angular在摘要周期中通过dirty checking检测更改。

$timeout is also doing $apply ($rootScope.$apply())

检查Angular source code

我可以建议创建帮助函数来处理它。例如:

var ngAware = function (fnCallback) {
    return function () {
        var result = fnCallback.apply(this, arguments);    
        $scope.$apply();
        return result;
    };   
};   

// usage
function func1 () {
    // impl...
}
var ngFunc1 = ngAware(func1);
// or
var func2 = ngAware(function func2 () {
    // impl...
});

答案 1 :(得分:0)

您确实需要apply()

在集成第三方库(例如jQuery)时使用

apply()。在大多数情况下,如果您没有连接第三方JavaScript库,则可以通过使用内置绑定机制来避免$apply()

例如,以下代码段将使用3秒超时回调来调用func1。然后,func1将操作范围变量something,视图将更新,而无需触发$apply()

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

app.controller('MainCtrl', function($scope) {
  $scope.value = 'Hello';
});


app.directive('myDirective', function ($timeout) {
    return {
        restrict: 'E',
        template:'<h1>{{something}}</h1>',
        scope: {
            'something': '='
        },
        link: function (scope, el, attr) { 
             function func1(){
                scope.something += ' ' + scope.something;
             }

             $timeout(func1, 3000);
        }
    }
});

html

<body ng-controller="MainCtrl">
   <my-directive something="value"></my-directive>
</body>

http://plnkr.co/edit/42VYs0W2BC5mjpaVWQg3?p=preview

  • 也许如果你解释一下你的用例,我可以扩展我对你特定需求的回答

答案 2 :(得分:0)

将函数包装在$ scope内。$ apply()

检查一下:

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

app.controller('MainCtrl', function($scope) {
    $scope.value = 'Hello';
});


app.directive('myDirective', function ($timeout) {
    return {
        restrict: 'E',
        template:'<h1>{{something}}</h1>',
        scope: {
            'something': '='
        },
        link: function (scope, el, attr) { 
            scope.$apply(function(){

                function func1(){
                    //some stuff
                }

                function func2(){
                    //some stuff
                }

                function func3(){
                    //some stuff
                }
            })
        }
    }
});