Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对指令中的每个函数执行默认操作_Javascript_Angularjs - Fatal编程技术网

Javascript 对指令中的每个函数执行默认操作

Javascript 对指令中的每个函数执行默认操作,javascript,angularjs,Javascript,Angularjs,我创建了一些具有某些功能的指令,如下所示: myCtrl.directive('myDirective', function () { return { restrict: 'E', scope: { 'something': '=' }, link: function (scope, el, attr) { function func1(){

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

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个函数! 此外,我正在使用一些第三方库,如
d3.js
。某些事件(如单击的
被限制调用这些函数。

是否需要
apply()
? 集成第三方库(如jQuery)时使用
apply()。在大多数情况下,如果不连接第三方javascript库,可以使用内置绑定机制避免
$apply()

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

var-app=angular.module('plunker',[]);
应用程序控制器('MainCtrl',函数($scope){
$scope.value='Hello';
});
app.directive('myDirective',函数($timeout){
返回{
限制:'E',
模板:“{{something}}”,
范围:{
“某物”:“=”
},
链接:函数(范围、el、属性){
函数func1(){
scope.something+=''scope.something;
}
$timeout(func1,3000);
}
}
});
html


  • 也许,如果您对您的用例进行更多的解释,我可以根据您的具体需求扩展我的答案

将函数包装在$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
                }
            })
        }
    }
});
var-app=angular.module('plunker',[]);
应用程序控制器('MainCtrl',函数($scope){
$scope.value='Hello';
});
app.directive('myDirective',函数($timeout){
返回{
限制:'E',
模板:“{{something}}”,
范围:{
“某物”:“=”
},
链接:函数(范围、el、属性){
作用域$apply(函数(){
函数func1(){
//一些东西
}
函数func2(){
//一些东西
}
函数func3(){
//一些东西
}
})
}
}
});

真正的事实是,无论何时更改角度摘要周期之外的内容,都需要调用
$scope.$apply()
。Angular通过在摘要循环中检测变化

$timeout也在执行$apply($rootScope.$apply())

检查

我的建议是创建一个助手函数来处理这个问题。例如:

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...
});

如果您的指令中有通用功能(圆形、方形等),则应将其分组。例如,我们可以有一个指令拖动

.directive('ngDraggable', [function () {

    return {
        link: function ($scope) {

            var stopHandler = function () {

                $scope.apply(function () {
                    // Code to handler the end of the dag event

                    // Notify the other directive.
                    $scope.$emit('dragStopped', data);
                });
            };

            // Initialization of the drag functionality.
        }
    }
}])
你可以用作

<div ng-circle ng-draggable></div>

所以,你赚了三分钱。首先,circle指令可以在其范围内进行更改,而无需调用
$apply
,因为
$emit
已经在摘要循环中。其次,仅在必要时使用
$apply
。第三,您可以在最小的作用域中使用
$apply
,并使用较少的子对象,从而提高性能

您可以将此答案与@sasko_dh的答案合并


也许这个函数对您有用。

您的函数附加到
范围
,对吗?即
scope.func1=function(){}?@sp00m不,它们不是。您是否尝试在指令中声明控制器?@TahsisClaus请检查更新部分。理论上,您可以为常规操作(如拖动事件)使用指令触发器,选择要调用的函数之一,然后在函数完成后调用$apply。如果看不到指令的完整代码,很难说。在指令中使用$apply并不像在angular之外的任何接口(DOM和浏览器事件也是如此)所需要的那样令人讨厌。许多ng指令使用$apply。我认为您的解决方案非常接近我需要的,唯一的区别是我提到的函数是一些事件,例如单击或拖动事件。您可以将它们用作常规函数。示例:$('stg')。单击(func2);或$('stg')。单击(ngAware(函数(事件){//impl..}));您能在fiddle或其他地方制作一个样本吗?是的,这里有一个简单的例子:这里不是$scope。$apply()我们显示了额外的警报。
.directive('ngDraggable', [function () {

    return {
        link: function ($scope) {

            var stopHandler = function () {

                $scope.apply(function () {
                    // Code to handler the end of the dag event

                    // Notify the other directive.
                    $scope.$emit('dragStopped', data);
                });
            };

            // Initialization of the drag functionality.
        }
    }
}])
<div ng-circle ng-draggable></div>