【问题标题】:AngularJS directive ng-click parameters not being passedAngularJS指令ng-click参数没有被传递
【发布时间】:2012-12-23 11:52:03
【问题描述】:

我正在尝试构建一个指令来为分页控件(Twitter Bootstrap 样式)输出一些 HTML 格式的代码,该指令需要从我的控制器范围内获取当前页面和总页面,并且当分页链接是点击触发我的控制器上的一个函数来改变页面(建立一个 url 并调用 $location 来改变页面)。

我观看了许多优秀的 YouTube angularjs 视频 (http://www.youtube.com/watch?v=nKJDHnXaKTY),但似乎没有一个涵盖这种特殊的复杂场景。

任何帮助都会很棒!

这里是 jsfiddle,使它更清晰:

http://jsfiddle.net/philjones88/dVFDT/

我无法工作的是传递参数,我得到了:

changing page to: undefined

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    在你的指令中添加 changePage 调用(我知道它不是你想要的)。让它使用相同的参数调用父作用域 changePage。

    $scope.changePage = function(index){
        console.log("running changePage");
        $scope.$parent.changePage(index); //might want to check if the parent scope has this too
    }
    

    作为另一个提示,在指令中,您不应该在被发送的变量前面使用 $。在这种情况下,这将是 $scope、$element、$attrs。您在控制器(不是链接函数)的作用域前面看到的 $ 是为了让您知道它正在被注入。它没有被注入到链接控制器中。例如,这里:

    app.directive("pager", function ($injector1, $injector2) {
    

    这是注入参数的去向,您希望能够区分这两者。我意识到这有点偏离轨道,我希望我对 changePage 的建议是您正在寻找的。​​p>

    编辑:更新小提琴http://jsfiddle.net/dVFDT/48/

    为未来的搜索者修改答案:您通过 click 方法传入的函数如下:

    ..... click="changePage()".....
    

    需要改成:

    ..... click="changePage".....
    

    这意味着您传递的是函数而不是函数调用。这意味着在您的指令中,当您连接 changePage 回调时,您正在使用如下索引调用函数:

    changePage()(1)
    

    这就是你变得不确定的原因。

    【讨论】:

    • 抱歉,将完全重写问题以包含问题的简化 jsfiddle。
    • 修改了你的小提琴来做我建议的事情:jsfiddle.net/dVFDT/38。发布小提琴让它变得容易多了:)
    • 问题是使用$parent的方式忽略了我传入的方法名,也就是说指令是直接耦合到控制器的
    • 再次更新小提琴,不再使用父级。您必须将函数作为变量传递,而不是函数本身。
    • 哇。在职的。指令让我头疼,我怀疑有一天它会很自然,就像我现在可以不加思索地编写 Map/Reduce...谢谢!
    【解决方案2】:

    我不完全理解,但是在你的指令结束时你想执行你的控制器的功能吗?

    试试:

    <div class="pagination">
       <pager current-page="currentPage" total-pages="totalPages" query="query" callback="changePage()"></pager>
    </div>
    

    【讨论】:

    • 通过指令的作用域功能发现了这一点。我在这里显示的代码太复杂,无法最终显示问题(我在其中构建了一个带有 ng-click 的字符串链接,但 ng-click 不起作用)
    【解决方案3】:

    我意识到这个问题有点老了,但实际上还有另一种方法可以解决这个问题,不需要重新编译或调用父作用域。但是,它确实需要以稍微不同的方式从指令中调用该方法。

    你可以在这里看到小提琴:Fiddle

    最感兴趣的那一行是在模板声明中。对 onClick 的调用要求您将对象传递给它,而不仅仅是值。

        template: 
        "<div ng:repeat='i in [] | range:totalPages'> " +
            "<a ng:click='onClick({page: i + 1})'>Page {{i + 1}}</a>" +
        "</div>",
    

    这也使用了来自this answer from Gloopy 的过滤器,以便在ng:repeat 中迭代n 的次数。这允许绑定全部发生在模板中。

    【讨论】: