angularjs - 隔离多个不同指令之间的范围

时间:2014-09-09 15:51:16

标签: angularjs

我正在尝试创建三个需要一起通信的不同指令,这不是一个真正的问题,但我想探讨使用隔离范围的可能性,或者至少尽可能小的范围他们之间。

因为不鼓励直接在控制器范围上共享,所以我制定了这个以试图解决这个问题。我立即看到的唯一解决方案是在同一个单一指令中制作所有三个行为,以便它们都使用相同的范围 - 但这非常混乱。

这是一个非常简洁的例子,说明它的工作原理。完整的代码很长,如果没有很多额外的上下文,它就无用了。我试图将其削减到我需要帮助的地方。

1。有没有更好的方法在指令之间共享这些scope属性?

2。我可以使用隔离范围来减少控制器上的混乱和负载吗?

3。共享信息的原因有点难以解释。

指令

angular.module('app', [])
.directive('dataSourceUrl', ['$parse', function($parse) {
   return {
        restrict: 'A',
        priority: 10,
        link: function(scope, element, attributes) {
            var path = attributes.dataSourceUrl;

            angular.extend(scope.options, {
                /* more code */
            });
        }
   }
}])
.directive('dataSourceOptions', 
    ['$parse', function($parse) {
    return {
        restrict: 'A',
        priority: 9,
        link: function(scope, element, attributes) {
            var options = scope.$eval(attributes['dataSourceOptions']);

            angular.extend(scope.options, {
                /* more code */
            });
        }
    }
}])
.directive('dataSourceColumns', 
    ['$parse', function($parse) {
    return {
        restrict: 'A',
        priority: 9,
        link: function(scope, element, attributes) {
            var columns = scope.$eval(attributes.dataSourceColumns);

            angular.forEach(columns, function(value, key) {
                switch(value) {
                    case "Id":
                        scope.options.columns.push({ field: "Id" /* more code */ });
                        break;
                    case "Name":
                        scope.options.columns.push({ field: "Name" /* more code */ });
                        break;
                    /* more code */
                }
            });
        }
    }
}]);

注释

我对角度的体验很少,我很新。我已经广泛研究了隔离范围,但事实证明它比我想象的要困难得多。我的目标是使用这样的指令......

<div kendo-grid data-source-url="'path/to/data'" 
     data-source-options="options" 
     data-source-columns="['Id','Name','Abbreviation','Group']">
</div>

2 个答案:

答案 0 :(得分:2)

你可以在同一个元素上有多个isolate stroped指令。虽然我记得,在某个地方读取它,多个孤立范围的指令确实共享范围。

您可以阅读有关范围here

的更多信息

关于在指令之间共享数据,指令是独立的还是处于父子关系中?

如果父子,则使用指令的require属性。并将数据仅传递给父指令并在子指令中访问它。

如果他们是兄弟或独立,则分别将数据传递给每个指令。

我们假设dataSourceUrl根据dataSourceOptions中的参数显示更改。那么你可以使用require属性。

.directive('dataSourceUrl', 
    ['$parse', function($parse) {
    return {
        restrict: 'A',
        require: 'dataSourceOptions'
        link: function(scope, iElement, iAttrs, ctrlOptions)
               {
                         //ctrlOption.showHeadeers or something
                }

答案 1 :(得分:1)

这是两个指令集成的小提琴

http://jsfiddle.net/Wijmo/MTKp7/

和代码是

angular.module("btst", []).
directive("btstAccordion", function () {
    return {
        restrict: "E",
        transclude: true,
        replace: true,
        scope: {},
        template:
            "<div class='accordion' ng-transclude></div>",
        link: function (scope, element, attrs) {

            // give this element a unique id
            var id = element.attr("id");
            if (!id) {
                id = "btst-acc" + scope.$id;
                element.attr("id", id);
            }

            // set data-parent on accordion-toggle elements
            var arr = element.find(".accordion-toggle");
            for (var i = 0; i < arr.length; i++) {
                $(arr[i]).attr("data-parent", "#" + id);
                $(arr[i]).attr("href", "#" + id + "collapse" + i);
            }
            arr = element.find(".accordion-body");
            $(arr[0]).addClass("in"); // expand first pane
            for (var i = 0; i < arr.length; i++) {
                $(arr[i]).attr("id", id + "collapse" + i);
            }
        },
        controller: function () {}
    };
}).
directive('btstPane', function () {
    return {
        require: "^btstAccordion",
        restrict: "E",
        transclude: true,
        replace: true,
        scope: {
            title: "@",
            category: "=",
            order: "="
        },
        template:
            "<div class='accordion-group' >" +
            "  <div class='accordion-heading'>" +
            "    <a class='accordion-toggle' data-toggle='collapse'> {{category.name}} - </a>" +

            "  </div>" +
            "<div class='accordion-body collapse'>" +
            "  <div class='accordion-inner' ng-transclude></div>" +
            "  </div>" +
            "</div>",
        link: function (scope, element, attrs) {
            scope.$watch("title", function () {
                // NOTE: this requires jQuery (jQLite won't do html)
                var hdr = element.find(".accordion-toggle");
                hdr.html(scope.title);
            });
        }
    };
})

你也可以从这个js看到手风琴的例子

https://github.com/angular-ui/bootstrap/blob/master/src/accordion/accordion.js