繁体   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