【问题标题】:AngularJS - ui-bootstrap accordion - using ng-controller inside ng-repeat doesn't workAngularJS - ui-bootstrap 手风琴 - 在 ng-repeat 中使用 ng-controller 不起作用
【发布时间】:2015-04-27 05:46:01
【问题描述】:

我正在尝试构建一个可在手风琴展开时显示更多详细信息的手风琴列表。这是模板的简化版本:

<body ng-controller="MainController as main">
    <accordion>
        <accordion-group ng-repeat="r in main.results" ng-controller="DetailsController as d">
            <accordion-heading ng-click="d.getDetails(r.id)">
                {{r.name}}
            </accordion-heading>
            <ul>
                <li ng-repeat="v in d.details">{{v.detail}}</li>
            </ul>
        </accordion-group>
    </accordion>
</body>

DetailsController 最初有一个空的 details 数组,但是当调用函数 getDetails() 时,该数组由服务填充(detailsS​​ervice 只是一个抽象的 $resource 调用)。这部分在不应用于手风琴时有效,但在这种特定情况下,点击手风琴标题时不会发生任何事情。见下文:

app.controller('DetailsController', function(detailsService) {
    var vm = this

    var details = []
    var detailsPopulated = false

    var getDetails = function(id) {
        console.log('getDetails()')
        if (!vm.detailsPopulated) {
            console.log('Getting details')
            detailsService.get({id: id}, function(data) {
                vm.details = data.results
                vm.detailsPopulated = true
            });
        }
    }

    return {
        details: details,
        getDetails: getDetails
    }

});

这个控制器在其他情况下也可以工作,但由于某种原因,手风琴头上的 ng-click 根本不会调用 getDetails 函数——如果是这样,我会在控制台中看到“getDetails()”,因为是 getDetails 函数的第一条语句。

更简单:使用模拟“详细信息”设置控制器不起作用。

app.controller('DetailsController', function() {
    var details = [{detail: 'Test'}]

    return {
        details: details
    }
});

模板:

<body ng-controller="MainController as main">
    <accordion>
        <accordion-group ng-repeat="r in main.results" ng-controller="DetailsController as d">
            <accordion-heading>
                {{r.name}}
            </accordion-heading>
            <ul>
                <li ng-repeat="v in d.details">{{v.detail}}</li>
            </ul>
        </accordion-group>
    </accordion>
</body>

即使是这个带有服务和 ng-click 删除的简化示例也不起作用。

任何人都可以提出解决方案吗?我也在尝试使用“controller as”技术而不是到处使用 $scope 来实现这一点。

【问题讨论】:

  • 你能创建一个小提琴/plunker吗?代码看起来不错。控制台中的任何错误?

标签: angularjs angularjs-ng-repeat angular-ui-bootstrap angularjs-ng-click


【解决方案1】:

您不能将ng-click 绑定到&lt;accordion-heading&gt;,因为ui.bootstrap 会为heading 使用不同的DOM。您可以查看developer console 以了解ui.bootstrap&lt;accordion-heading&gt; 翻译成DOM 的内容。

<div class="panel-heading">
    <h4 class="panel-title">
    <a href="" class="accordion-toggle" ng-click="toggleOpen()" accordion-transclude="heading"><span class="ng-scope ng-binding">Header 1</span></a>
    </h4>
</div>

我想你想动态加载accordion 的内容。实现此目的的一种方法是在accordion 打开$watch 并执行加载。我创建了这个fiddle 来展示这个想法。你必须注意的事情:

  1. 您不能将ng-controller 放在accordion-group 中,因为它会引发错误 multiple directive asking for isolated scope。这是因为&lt;accordion-group&gt; 是一个隔离作用域,而角度不允许两个作用域:一个来自控制器作用域,一个来自指令隔离范围 绑定到同一个 htmlReference。解决此问题的一种方法是将divng-controllerng-repeat 放在accordion-group 之外。

    <div ng-repeat="r in main.results" ng-controller="DetailsController as d">
        <accordion-group>
           ...
        </accordion-group>
    </div>
    
  2. 您可以将attrs is-open 添加到accordion-group$watch 以进行更改并执行加载Accordion 指令将在 openclose accordion 时更改 is-open 值。

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 2014-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多