AngularJS ui-bootstrap 手风琴无法在过滤的 ng-repeat 中访问手风琴外部的变量

AngularJS ui-bootstrap accordion cannot access variable outside accordion in filtered ng-repeat

我正在使用 AngularJS UI Bootstrap 的手风琴。我在手风琴内部使用 ng-repeat 和过滤器。现在的问题是我无法访问 <accordion> 之外的过滤变量。如果我放弃手风琴并使用简单的 HTML 它工作正常。

<div ng-app="myApp">
  <div ng-controller="AccordionCtrl">
    <div>outside accordion{{filteredCampaigns}}</div>
    <input type="text" ng-model="q" placeholder="filter" />
    <accordion class="accordion" close-others="true">
      <div>inside accordion{{filteredCampaigns}}</div>
      <accordion-group  ng-repeat="campaign in filteredCampaigns=(campaigns | filter:q)">
        <accordion-heading>
          <h3>{{campaign.title}}</h3>
        </accordion-heading>
        <p>{{campaign.content}}</p>
      </accordion-group>
    </accordion>
  </div>
</div>
<script>
  var app = angular.module('myApp', ['ui.bootstrap']);
  app.controller('AccordionCtrl', ['$scope',
  function ($scope) {
      $scope.campaigns = [{
          title: "Test1",
          content: "file1.html"
      }, {
          title: "Test2",
          content: "file2.html"
      }, {
          title: "Test3",
          content: "file3.html"
      }];
  }]);
</script>

我还创建了 fiddle here

由于您在 ng-repeat 之外使用它,因此您看不到该变量,因为 ng-repeat 创建了它自己的范围。

您可以使用控制器并手动使用过滤器来检索过滤的对象:

$scope.getFilteredCampaings = function () {
        $scope.filteredCampaigns = $filter('filter')($scope.campaigns, $scope.q);
        return $scope.filteredCampaigns;
}

Fiddle

<accordion> 创建一个隔离范围,并且 filteredCampaigns 仅在该范围内可用,在父范围内不可用。要将其添加到父范围,请使用 $parent:

ng-repeat="campaign in $parent.filteredCampaigns=(campaigns | filter:q)">

另一种解决方案是在父范围内创建一个对象,其中包含 filteredCampaings 的参数:

// AccordionCtrl
$scope.filteredValues = {
    filteredCampaings: []
};

ng-repeat="campaign in filteredValues.filteredCampaigns=(campaigns | filter:q)"

这是因为 angular-ui 附带的子指令具有不将此新 filteredCampaigns 变量反映到控制器范围的子范围。

第一个选项 - 破解它,

1) 定义一个对象来包含filteredCampaigns动态变量

$scope.context = {};   

2) 将您的 accordion-group 更改为:

<accordion-group ng-repeat="campaign in context.filteredCampaigns=(campaigns | filter:q)">

http://jsfiddle.net/Lryuvm9m/1/

<script>
    var app = angular.module('myApp', ['ui.bootstrap']);
    app.controller('AccordionCtrl', ['$scope',
    function ($scope) {

        $scope.context = {};
        $scope.campaigns = [{
            title: "Test1",
            content: "file1.html"
        }, {
            title: "Test2",
            content: "file2.html"
        }, {
            title: "Test3",
            content: "file3.html"
        }];
    }]);
</script>

<div ng-app="myApp">
    <div ng-controller="AccordionCtrl">
        <div>outside accordion {{context.filteredCampaigns}} </div>
        <input type="text" ng-model="q" placeholder="filter" />      
        <accordion class="accordion" close-others="true">
            <div>inside accordion{{context.filteredCampaigns}}</div>
            <accordion-group  ng-repeat="campaign in context.filteredCampaigns=(campaigns | filter:q)">
                <accordion-heading>
                    <h3>{{campaign.title}}</h3>
                </accordion-heading>
                <p>{{campaign.content}}</p>
            </accordion-group>
        </accordion>
    </div>
</div>

第二个选项 - 使用 Controller as

我建议使用 Controller as,因为它会让您更好地控制控制器范围内定义的内容和未定义的内容

http://jsfiddle.net/gntt6h5b/

<script>
    var app = angular.module('myApp', ['ui.bootstrap']);
    app.controller('AccordionCtrl', ['$scope',
    function () {
        var vm = this;
        vm.campaigns = [{
            title: "Test1",
            content: "file1.html"
        }, {
            title: "Test2",
            content: "file2.html"
        }, {
            title: "Test3",
            content: "file3.html"
        }];
    }]);
</script>

<div ng-app="myApp">
    <div ng-controller="AccordionCtrl as vm">
        <div>outside accordion {{vm.filteredCampaigns}} </div>
        <input type="text" ng-model="q" placeholder="filter" />      
        <accordion class="accordion" close-others="true">
            <div>inside accordion{{vm.filteredCampaigns}}</div>
            <accordion-group  ng-repeat="campaign in vm.filteredCampaigns=(vm.campaigns | filter:q)">
                <accordion-heading>
                    <h3>{{campaign.title}}</h3>
                </accordion-heading>
                <p>{{campaign.content}}</p>
            </accordion-group>
        </accordion>
    </div>
</div>