如何将此功能转换为符合角度的功能?

时间:2014-05-30 03:02:03

标签: javascript angularjs twitter-bootstrap

我正在将一个Bootstrap + jQuery主题转换为Angular JS,我遇到了一些麻烦。有一点是在主题的JS文件中提供的这种功能:

/* Sidebar Navigation functionality */
var handleNav = function() {

    // Animation Speed, change the values for different results
    var upSpeed     = 250;
    var downSpeed   = 250;

    // Get all vital links
    var allTopLinks     = $('.sidebar-nav a');
    var menuLinks       = $('.sidebar-nav-menu');
    var submenuLinks    = $('.sidebar-nav-submenu');

    // Primary Accordion functionality
    menuLinks.click(function(){
        var link = $(this);

        if (link.parent().hasClass('active') !== true) {
            if (link.hasClass('open')) {
                link.removeClass('open').next().slideUp(upSpeed);

                // Resize #page-content to fill empty space if exists
                setTimeout(resizePageContent, upSpeed);
            }
            else {
                $('.sidebar-nav-menu.open').removeClass('open').next().slideUp(upSpeed);
                link.addClass('open').next().slideDown(downSpeed);

                // Resize #page-content to fill empty space if exists
                setTimeout(resizePageContent, ((upSpeed > downSpeed) ? upSpeed : downSpeed));
            }
        }

        return false;
    });

    // Submenu Accordion functionality
    submenuLinks.click(function(){
        var link = $(this);

        if (link.parent().hasClass('active') !== true) {
            if (link.hasClass('open')) {
                link.removeClass('open').next().slideUp(upSpeed);

                // Resize #page-content to fill empty space if exists
                setTimeout(resizePageContent, upSpeed);
            }
            else {
                link.closest('ul').find('.sidebar-nav-submenu.open').removeClass('open').next().slideUp(upSpeed);
                link.addClass('open').next().slideDown(downSpeed);

                // Resize #page-content to fill empty space if exists
                setTimeout(resizePageContent, ((upSpeed > downSpeed) ? upSpeed : downSpeed));
            }
        }

        return false;
    });
};

这是一个在应用程序启动时运行的功能,负责在侧栏上附加功能。基本上,这只是简单地将句柄附加到侧栏上链接的click事件,以添加下拉效果并在需要时调整主容器的大小。

那很好,但是,我没有看到如何使这个“角度兼容”的东西。我的意思是,我可以在视图加载事件上运行它,但这似乎不是一个好主意。我想我需要使用指令,但在这种情况下我不知道如何。这不是应用于一个元素的东西,实际上是一堆应用于一堆元素的东西。

更重要的是,它会干扰断开连接的元素:这也会调整主容器的大小,因此这会在页面的某个其他元素上调用某些功能。

如何将此特定功能转换为符合角度的内容?

编辑 我的想法是创建两个指令menu-linksubmenu-link,然后在每个链接本身上应用此指令。指令中的代码与此处的代码相同。然而,这似乎并不实用,因为我需要一遍又一遍地执行该指令。

1 个答案:

答案 0 :(得分:2)

听起来你可能做了太多的工作......你是否也按照评论中的说明看到http://angular-ui.github.io/bootstrap/,将http://plnkr.co放在一起显示你到目前为止的尝试,你可以毫无疑问地得到一个解决方案(如果您使用IRC加入#angularjs会议室并寻求帮助)

修改

Hiya,w / r / t评论,np和yes你想要做的事情可能会涉及一些问题。如果指令具有直接的父子关系,或者指令位于可以使用" require"的同一元素上,则可以在指令之间进行通信。定义指令时的属性,因此它可以要求将来自另一个指令的控制器注入到它的链接函数中(参见$ compile文档关于"要求"如果感兴趣的话)。

https://docs.angularjs.org/api/ng/service/ $编译

https://docs.angularjs.org/guide/directive

除此之外,基本上还有另外两种方法可以在不同的元素之间进行通信,我更喜欢第一种。第一种方法是使用注入两个组件的服务,这些组件需要共享一些信息,并且数据在服务中定义,因此当该服务(单例)注入各种控制器时,它们具有共享数据存储和一些功能可以与事物之间的沟通。因此,对于您的示例,您使用左侧导航,我假设您要跟踪点击次数并在右侧面板中执行某些操作。您只需存储有关服务中所有事物状态的信息即可。

你可能采取的另一种方式是使用带有$ emit,$ on和$ broadcast的事件,但我认为如果你想让一个指令在"小部件中可用,那么这只适用于账单。 #34;小部件只是发出事件并以各种方式响应在它们上广播的事件的体系结构。关于范围的父/子关系,这可能会有问题,并且可能通过触发事件等的事件导致疯狂的无限循环等。

通常在Angular中,您将指令应用于您希望它们生效的元素。指令定义可能有一个注入其中的服务,为其提供更多信息,或者数据可以通过指令的范围传递(如果您将其隔离),然后您可以将服务注入控制器以获取所需的数据进入指令范围...抱歉,我知道这是抽象的,所以如果你想在某个地方做更多的澄清,请告诉我。

另一种观察方式是你要创建一个"视图模型"它存在于您的服务中,因为您希望它在各种控制器中保持不变。

以下是我发布的几个例子: Angular $http vs service vs ngResource

请不要将上述链接视为您尝试做的事情,而只是一个服务示例,其中包含一些以某种方式更新的数据,并将其注入要在视图中使用的服务。从控制器将数据分配给范围的属性,以便可以在视图中访问它。导致数据更新的事情并不重要,只要它在更改数据后调用$ rootScope。$ apply()以便更新视图。

在此处查看script.js,了解对http://plnkr.co/edit/ABQsAxz1bNi34ehmPRsF?p=preview

上发生的事情的评论

要注意在最后一个plunkr中建议在控制器中设置监视器以观看服务的方法,因为它使测试更加困难并且只是不必要,请参阅第一篇文章以及我已经决定不再使用的内容一个好主意,并改为使用angular.copy。