8

我对所有这些角度都很陌生...

我有一个自定义指令,我们称之为 myDar。在这个指令中,我定义了一个链接函数。在我的 html 中,我想使用该指令的多个嵌套标签,如下所示:

<myDar id="outer"><myDar id="inner"></myDar></myDar>

我希望首先执行“外部”的链接功能。我该怎么做呢?

这是一般的问题。如果它有帮助,那么我真正想做的是创建包装 jquery ui 布局的指令(链接到网站)。所以我有一个“ui-layout”指令和“center”、“west”等指令。在“ui-layout”指令中,我调用了$(tElm).layout(options). 创建嵌套布局时遇到问题:

<ui-layout class="layout-container">
    <ui-layout-center>
        <ui-layout>
            <ui-layout-center>inner center</ui-layout-center>
            <ui-layout-west>inner west</ui-layout-west>
        </ui-layout>        
    </ui-layout-center>
    <ui-layout-west>west</ui-layout-west>
</ui-layout>

Angular首先执行内部“ui-layout”指令的链接功能,但要让jquery ui布局插件工作,它需要先调用$(tElm).layout(options)外部,否则布局无法正确呈现。

4

2 回答 2

8

为此,您将利用指令的控制器。它将是一个,它定义了一个注册嵌套控制器的方法和另一个用于$(...).layout(...)在此元素上执行所需命令(此处),然后在其所有子元素上执行的方法。这意味着外部指令负责协调布局的创建。

完整的示例代码是:

app.directive("y", function() {
    function Controller($element) {
        this.$element = $element;
        this.children = [];
    }

    Controller.prototype.register = function(child) {
        this.children.push(child);
    };

    Controller.prototype.execute = function() {
        console.log("PAYLOAD: " + this.$element.attr("id"));
        for( var i=0; i < this.children.length; i++ ) {
            this.children[i].execute();
        }
    };

    return {
        require: "y",
        controller: ["$element", Controller],
        link: function(scope, element, attrs, ctrl) {
            var e = element.parent(), nested = false;
            while( e != null ) {
                if( e.controller("y") != null ) {
                    e.controller("y").register(ctrl);
                    nested = true;
                    break;
                }
                e = e.parent();
                if( typeof(e.tagName) === "undefined" ) break; //XXX Needed, at least for fiddle
            }
            if( !nested ) ctrl.execute();
        }
    };
});

将该行替换为console.log("PAYLOAD: " + this.$element.attr("id"));要运行的实际代码。请参阅相关小提琴:http: //jsfiddle.net/8xSjZ/

如果外部指令与当前指令不同,则获取父控制器就像要求"?^y". 在这种情况下,它为我们提供了当前控制器,因此我们必须自己循环 ( e.parent())。

于 2014-01-15T16:46:53.117 回答
2

根据具体的用例,一个compile函数可能很合适。compile函数在link函数之前执行,并且 - 更重要的是 - 以相反的顺序执行。首先是父母的意思。

app.directive("ui-layout", function() {
  return {
    restrict: 'E',
    compile: function(element, attrs) {
               //do layout stuff here
               //return a link function or nothing

另一种解决方案可能是使用$timeout.

app.directive("ui-layout-center", function($timeout) {
  return {
    restrict: 'E',
    link: function(scope, element, attrs) {
            $timeout(function() {
              //do layout stuff later
             }, 0);  
于 2014-01-15T20:34:13.873 回答