簡體   English   中英

Angular指令父范圍

[英]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) {})您刪除了傳遞給指令的實際數據的引用。 因此,值不會更新。

因此,要解決此問題,您有幾種選擇:

  1. 更改排序代碼以不重新分配完整的scope.data變量RECOMMENDED (使用內置sort方法)
  2. 使用scope.$emit()將修改后的data傳遞到父范圍
  3. 或使用您不想使用的$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 jqLit​​e處理click事件時,代碼需要通知AngularJS框架。

從文檔中:

$apply([exp]);

$apply()用於從角度框架外部以角度執行表達式。 (例如,來自瀏覽器DOM事件,setTimeout,XHR或第三方庫)。 因為我們正在調用有角度的框架,所以我們需要執行異常處理的適當范圍生命周期,並執行監視

-AngularJS $ rootScope.scope API參考-$ apply

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM