[英]Angular directive parent scope
我正在建立一个装饰表标题项并在click事件后对数据进行排序的指令。 我无法使用指令范围将数据模型上的更改应用于父范围。
vm.data是父作用域上的一个数组,其中包含我要在指令中排序的数据。 单击后,指令中的数据对象已更改,但父对象仍处于相同顺序。
我不想使用$ parent访问父范围,我想念的是什么?
<th sortable="browser" data="vm.data">Browser</th>
指令代码:
angular
.module("app")
.directive("sortable", ['lodash', sortableDirective]);
function sortableDirective(lodash) {
return {
restrict: "A",
scope:{
data:"="
},
controller:function($scope){
},
link: function (scope, element, attributes) {
var sorted = undefined;
var col = attributes['sortable'];
var oldClass = 'sorting'
attributes.$$element.addClass(oldClass);
$(element).on("click", sort);
function changeClass(){
if(sorted=='asc'){
attributes.$$element.removeClass(oldClass);
attributes.$$element.addClass('sorting_asc');
oldClass = 'sorting_asc';
}
else if(sorted=='desc'){
attributes.$$element.removeClass(oldClass);
attributes.$$element.addClass('sorting_desc');
oldClass='sorting_desc';
}
}
function sort() {
if (sorted == 'asc') {
sorted = 'desc';
}
else {
sorted = 'asc';
}
scope.data = lodash.sortBy(scope.data, function (o) {
return o[col];
});
if (sorted == 'desc') {
lodash.reverse(scope.data);
}
changeClass();
}
}
};
}
这是因为您正在使用jQuery来侦听元素上的更改。 因此,只需更改此行:
$(element).on("click", sort);
至
element.on("click", sort);
如果jQuery不可用,第二个属性ie element
已经是jQlite的实例,如果jQuery可用,它将是jQuery的实例。
在任何情况下,有一种方法可用.on
其中将在值变化来执行。 由于您再次将其包装到$()
,因此Angular尚未收到有关数据更改的通知。
在您的代码的第二遍中,我看到了实际的问题。 您正在sort()
方法中重新分配完整的scope.data
,这会破坏Javascript(或任何OOPS编程)的引用行为。
仅当您继续修改SAME参考变量时,按引用传递才有效。 注意到这个词, SAME ?? 通过编写scope.data = lodash.sortBy(scope.data, function (o) {})
您删除了传递给指令的实际数据的引用。 因此,值不会更新。
因此,要解决此问题,您有几种选择:
scope.data
变量RECOMMENDED (使用内置sort
方法) scope.$emit()
将修改后的data
传递到父范围 $parent
属性 双向绑定将在每个摘要循环上更新父级,但单击处理程序需要使用$apply
调用该摘要循环:
link: function (scope, element, attributes) {
var sorted = undefined;
var col = attributes['sortable'];
var oldClass = 'sorting'
element.addClass(oldClass);
//REPLACE this
//$(element).on("click", sort);
//
//WITH this
element.on("click", function (e) {
sort();
scope.$apply();
});
function changeClass(){
if(sorted=='asc'){
element.removeClass(oldClass);
element.addClass('sorting_asc');
oldClass = 'sorting_asc';
}
else if(sorted=='desc'){
element.removeClass(oldClass);
element.addClass('sorting_desc');
oldClass='sorting_desc';
}
}
ng-click
指令自动调用$apply
但是当AngularJS jqLite处理click事件时,代码需要通知AngularJS框架。
从文档中:
$apply([exp]);
$apply()
用于从角度框架外部以角度执行表达式。 (例如,来自浏览器DOM事件,setTimeout,XHR或第三方库)。 因为我们正在调用有角度的框架,所以我们需要执行异常处理的适当范围生命周期,并执行监视 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.