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>