所以我有这个名为say mySave
的指令,它几乎就是这个
app.directive('mySave', function($http) {
return function(scope, element, attrs) {
element.bind("click", function() {
$http.post('/save', scope.data).success(returnedData) {
// callback defined on my utils service here
// user defined callback here, from my-save-callback perhaps?
}
});
}
});
元素本身看起来像这样
<button my-save my-save-callback="callbackFunctionInController()">save</button>
callbackFunctionInController现在只是
$scope.callbackFunctionInController = function() {
alert("callback");
}
当我在my-save指令中console.log()
attrs.mySaveCallback
时,它只给了我一个字符串callbackFunctionInController()
,我读了somewhere我应该$解析它,它会是很好,所以我试着$parse(attrs.mySaveCallback)
给了我一些功能,但几乎没有我想要的那个,它让我回来了
function (a,b){return m(a,b)}
我做错了什么?这种方法从一开始就有缺陷吗?
答案 0 :(得分:61)
所以最好的方法是使用ProLoser建议的隔离范围
app.directive('mySave', function($http) {
return {
scope: {
callback: '&mySaveCallback'
}
link: function(scope, element, attrs) {
element.on("click", function() {
$http.post('/save', scope.$parent.data).success(returnedData) {
// callback defined on my utils service here
scope.callback(); // fires alert
}
});
}
}
});
要将参数传递回控制器,请执行此操作
[11:28] <revolunet> you have to send named parameters
[11:28] <revolunet> eg my-attr="callback(a, b)"
[11:29] <revolunet> in the directive: scope.callback({a:xxx, b:yyy})
答案 1 :(得分:12)
有很多方法可以解决你正在做的事情。你应该知道的第一件事是,一旦DOM元素被模板引擎渲染出来就会调用$http.post()
,就是这样。如果你把它放在重复中,那么将对转发器中的每个新项目进行调用,所以我猜这绝对不是你想要的。如果它是那么你真的没有正确设计东西,因为仅存在DOM不应该指示对后端的查询。
无论如何,直接回答你的问题;如果您在$ parse上阅读虽然糟糕的文档,它会返回一个评估表达式。通过将范围传递给evaluate on来执行此函数时,将返回您传递的范围上该表达式的当前状态,这意味着您的函数将被执行。
var expression = $parse(attrs.mySave);
results = expression($scope); // call on demand when needed
expression.assign($scope, 'newValu'); // the major reason to leverage $parse, setting vals
是的,一开始有点令人困惑,但你必须明白$ scope会在异步应用程序中不断变化,而这一切都与你想要确定的价值有关,而不仅仅是如何。 $parse
对于您希望能够为其分配值的模型的引用更有用,而不仅仅是从中读取。
当然,您可能希望了解如何创建隔离范围或如何$eval()
表达式。
$scope.$eval(attrs.mySave);
答案 2 :(得分:9)
您可以使用.$eval在给定范围内执行语句
app.directive('mySave', function($http) {
return function(scope, element, attrs) {
$http.post('/save', scope.data).success(returnedData) {
// callback defined on my utils service here
// user defined callback here, from my-save-callback perhaps?
scope.$eval(attrs.mySaveCallback)
}
}
});
道明:Demo
如果要在指令和控制器之间共享数据,可以使用双向绑定
app.controller('AppController', function ($scope) {
$scope.callbackFunctionInController = function() {
console.log('do something')
};
$scope.$watch('somedata', function(data) {
console.log('controller', data);
}, true);
});
app.directive('mySave', function($http, $parse) {
return {
scope: {
data: '=mySaveData',
callback: '&mySaveCallback' //the callback
},
link: function(scope, element, attrs) {
$http.get('data.json').success(function(data) {
console.log('data', data);
scope.data = data;
scope.callback(); //calling callback, this may not be required
});
}
};
});
演示:Fiddle
答案 3 :(得分:4)
scope: {
callback: '&mySaveCallback'
}
明确设置范围可能是一个很好的解决方案,但如果您希望到达原始范围的其他部分,则不能,因为您刚刚覆盖它。出于某种原因,我需要到达范围的其他部分,所以我使用与ng-click相同的实现。
在HTML中使用我的指令:
<div my-data-table my-source="dataSource" refresh="refresh(data)">
指令内部(未明确设置范围):
var refreshHandler = $parse(attrs.refresh);
scope.$apply(function () {
refreshHandler( {data : conditions}, scope, { $event: event });
});
有了这个,我可以在控制器中调用该函数并将参数传递给它。
在控制器中:
$scope.refresh= function(data){
console.log(data);
}
并正确打印出条件。
答案 4 :(得分:0)
这对我有用
在视图脚本中
<tag mycallbackattrib="scopemethod">
指令内
$scope[attrs.mycallbackattrib](params....);
它被正确调用并且params被传递,但可能不是最好的“有角度的方式”。
答案 5 :(得分:0)
您应该使用ng-click
而不是创建自己的指令。
答案 6 :(得分:0)
app.directive('mySave', function($http, $parse) {
return {
scope: {
data: '=mySaveData',
callback: '&' //the callback
},
link: function(scope, element, attrs) {
$http.get('data.json').success(function(data) {
console.log('data', data);
if (scope.callback()) scope.callback().apply(data);
});
}
};
});