我正在构建一个指令,用于装饰表头项目并根据单击事件对数据进行排序。我无法使用指令作用域将数据模型上的更改应用到父作用域。
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 不可用,第二个属性即 element
已经是 jQlite 的实例,如果 jQuery 可用,则将是 jQuery 的实例。
无论如何,有一个方法可用 .on
这将在值更改时执行。由于您再次将其包装到 $()
,因此 Angular 没有收到数据更改的通知。
编辑:
在第二次浏览您的代码时,我看到了实际的问题。您正在 sort()
方法中重新分配完整的 scope.data
,这会破坏 Javascript(或任何 OOPS 编程中)的引用传递行为。
仅当您继续修改 SAME 引用变量时,引用传递才会起作用。注意到这个词,相同?通过编写 scope.data = lodash.sortBy(scope.data, function (o) {})
,您删除了传递给指令的实际数据的引用。因此这些值不会更新。
因此,要解决此问题,您有以下几种选择:
- 更改排序代码,不要重新分配完整的
scope.data
变量推荐(使用内置sort
方法) - 使用
scope.$emit()
将修改后的data
传递到父作用域 - 或者使用您不想使用的
$parent
属性
关于javascript - Angular 指令父范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39063737/