[英]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.