Angular ng在加载所有内容之前包含$ on($ includeContentLoaded)

时间:2014-03-31 13:14:35

标签: javascript angularjs jquery-ui

我正在使用Angular ngInclude来包含一个包含一组嵌入式JqueryUI Accordions的部分HTML。

        <div ng-controller="startLessonController as slCtrl">
        <div class="accordionLevel">
            <div ng-repeat="level in course.level" >
              <h2> {{level.number}} - {{level.name}}: {{level.title}}</h2>
                <div >
                    <span ng-bind-html="level.description"></span>
                    <div class="accordionLesson" ng-include=" 'LessonMenuTemplate.html'  ">
                    </div>
                </div>
            </div>
        </div>
    </div>

我在$ scope。$ on($ includeContentLoaded)函数中包含了初始化手风琴的代码。

$scope.$on('$includeContentLoaded', function () {
    $( ".accordianLevel" ).accordion({
        header: "h2",
        collapsible: true,
        active:false,
        heightStyle:"content"
    });

以上对第一个手风琴级别(在ng-include之外)工作正常。然而,当$ includeContentLoaded触发时,所包含的HTML区域内的两个子手风琴初始化不在DOM中。

我通过在初始化内部手风琴之前加入一个延迟的setTimeout()来解决这个问题。

    $scope.$on('$includeContentLoaded', function () {
    $( ".accordionLevel" ).accordion({
        header: "h2",
        collapsible: true,
        active:false,
        heightStyle:"content"
    });
    setTimeout(function () {
        $( ".accordionLesson" ).accordion({
            collapsible: true,
            header: "h3",
            active:false,
            heightStyle:"content"
        });
        $( ".accordionPath" ).accordion({
            collapsible: true,
            header: "h4",
            active:false,
            heightStyle:"content"
        });
    }, 100);
});

我担心的是网络延迟可能导致上述失败,因为我的延迟是对DOM何时完全更新的猜测。我可以测试看看$(。accordionPath)是否为空并在另一次延迟后重试,但由于该元素有多次出现,我不知道它是否部分加载。

有没有更好的地方放置我的手风琴初始化逻辑?

1 个答案:

答案 0 :(得分:0)

这可能不是“Angular”设计实践中的最佳答案,但是,面对同样的问题,我已经通过以下方式“解决”了它:

创建一个小指令并将其限制为'A'(属性)。然后,将attribute-directive添加到您的手风琴<div> - 您可以将其嵌入到部分html或任何其他将通过$ compile运行的动态html代码中。这就是我的意思:

app.directive('myAccordionInit', function()
{
    var vDefinition =
    {
        restrict: 'A',
        link: function (scope, element, attrs)
        {
            setTimeout(function ()
            {
                element.accordion(
                {
                    collapsible: true,
                    header: h3,
                    active: false,
                    heightStyle: "content"
                });
            }, 100);
        }
    };
    return vDefinition;
});

超时仍然是必要的预防措施。

似乎发生的事情是,当你的“属性”指令被处理时,动态DOM几乎已经被构建,你的“属性”就在下面。您现在将代码附加到“元素”而不是类,Angular 传递给您有效的元素。因此,即使网络延迟很多,您的执行也会随之延迟。

顺便提一下,这种方法的另一个好处是,您可以将您的手风琴初始化设置为<div>的其他属性,即<div my-accordion-init header="h4">,然后修改您的指令以使用它们:

...

            element.accordion(
            {
                collapsible: true,
                header: attrs.header, // add others as necessary
                active: false,
                heightStyle: "content"
            });

...

希望这会有所帮助,

罗马