【问题标题】:AngularJS, directive element is nullAngularJS,指令元素为空
【发布时间】:2015-01-26 23:02:40
【问题描述】:

我正在努力将一个 jQuery 插件移植到 AngularJS,只是因为它看起来很有趣。 过去,在使用 jQuery 时,我使用 jQuery 来操作 DOM。所以,我在 jQuery 中有一个函数来加载插件,并且在那个函数中是操作 DOM。

现在,在使用 AngularJS 时,我读到有 directives 用于该特定目的,但我找不到解决方案。

我有以下html:

<body class="officeui-space-no-margin officeui-space-no-padding">
    <!-- Defines the OfficeUI section. In this section, all the contents for the OfficeUI user interface will be written. -->
    <div ng-controller="OfficeUIController" id="OfficeUI">
        <div class="title officeui-align-center">
            <span>Here the title can go.</span>
        </div>

        <!-- Defines the main holder for the ribbon. -->
        <div id="ribbonHolder">
            <!-- Render the template for the ribbon. -->
            <ng-include src="'Partials/Templates/Ribbon/tabs.html'"></ng-include>
        </div>
    </div>

    <!-- Bottom scripts: Used for Initialization. -->
    <script type="text/javascript">
        // Initialize the 'ribbonHolder' element as a ribbon.
        $('#ribbonHolder').ribbon();
    </script>
</body>

您在这里看到我正在加载要渲染的模板,其内容可以在下面找到:

<ul role="tablist" class="officeui-space-no-margin officeui-space-no-padding">
    <!-- Render all the tabs in the collection. -->
    <tabs-container>
        <li role="tab" class="officeui-display-inline-block officeui-align-center" ng-repeat="tab in tabs">{{tab.Name|tabs}}</li>
    </tabs-container>
</ul>

在上面的模板中,我确实有一个元素tabs-container,它应该是我的指令。 我有定义 AngularJS 东西的 JavaScript,包括注册这个指令:

var officeUIApplication = angular.module('OfficeUI.Ribbon.Controllers', []);
officeUIApplication.directive('tabsContainer', function() {
    var functionLink = function(scope, element, attrs) {
        console.log(element.children());
    };

    return {
        restrict: 'E',
        link: functionLink
    };
});

根据我对 AngularJS 非常有限的了解,我只是在学习它,它位于变量 functionLink 中,我应该在其中将附加事件处理程序的 DOM 操作到特定部分。

但是在functionLink里面我调用了下面的代码:

console.log(element.children());

但在控制台中,我确实看到这个特定元素是空的。 为什么会这样,这是好方法吗?

另一种方法,我已经将它包含在 jQuery 中,以便代码仅在 AngularJS 完成它的工作后执行,但我不喜欢这个特别的想法,另一方面,我如何创建一个传递选项和事件处理程序的 jQuery 插件,或者不再可能了,我实际上是在创建一个 AngularJS 插件吗?

感谢您的回复。

【问题讨论】:

    标签: javascript jquery html angularjs dom


    【解决方案1】:

    试试这个:

    officeUIApplication.directive('tabsContainer', function($timeout) {
        var functionLink = function(scope, element, attrs) {
             $timeout(function() { 
                  element.ribbon();
             });
        };
    
        return {
            restrict: 'E',
            link: functionLink
        };
    });
    

    jQuery 插件通常需要 DOM 准备好才能正确初始化。在 Angular 中,没有 DOM 就绪的真正概念。 $timeout 在渲染阶段之后执行,这就是它起作用的原因。

    【讨论】:

    • 你介意解释一下这发生了什么变化,我看到我现在已经传递了一个参数 $timeout,但不明白为什么需要这样做。此外,element.children() 不为 null,但在其上运行 jQuery 选择器不会返回任何元素:s
    • 好的,这更有意义,但是 AngularJS 超时函数中的事件,我无法操作 dom,如果我像上面显示的那样调用方法 element.ribbon,那么它就可以工作了,这是为什么?为什么我不能在指令中执行选择器?
    • 这是因为 DOM 还没有准备好。尝试做一个 angular.element(document).ready(function() { element.ribbon(); });从您的链接功能内部。这也应该有效。但是如果你想在模型改变时更新 UI 元素,那么使用 $timeout 代替
    • 好的,这更清楚了,只是一个额外的问题,看看下面的小提琴:为什么这里有元素而我的原始代码中没有? jsfiddle.net/E7xER/891
    • jQuery 选择器在链接函数中是可靠的。如果它不工作,其他的事情正在发生。
    猜你喜欢
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-28
    • 2014-06-11
    相关资源
    最近更新 更多