【问题标题】:$scope.$watch with filtered scopes as output$scope.$watch 过滤范围作为输出
【发布时间】:2016-10-05 09:35:09
【问题描述】:

本题基于the answer provided here

当另一个作用域 ($scope.switch) 设置为 true 时,我想输出应用到作用域 ($scope.names) 的 lodash 函数的结果,并输出该 lodash 函数的结果当$scope.switch 设置为false 时应用于filtered 范围。

所以我的ng-repeat 会是这样的:

<ul>
    <li ng-repeat="things in (filtered=(names | filter:filterType))">{{things}}</li>
</ul>

我使用两个ng-click 来更改 $scope.switch 的状态并应用/取消应用过滤器:

<a ng-click="switch = false; filterType=''">unswitch - No Filters</a><br><br>
<a ng-click="switch = true; filterType={name:'!Jimmy'}">switch - Not Jimmy</a>

我使用这段代码来观察$scope.switch的变化:

$scope.$watch('switch', function() {
      $scope.thingScope =$scope.switch ? _.map($scope.names,"styles") : _.map($scope.filtered,"styles");
    });

这是 all the code 的工作 plunkr(在这里更容易注意到问题)

问题是$scope.thingScope的输出与ng-repeat显示的值不对应(现在每次点击都显示上一个的值,也就是走一步在后面)。提前致谢!

【问题讨论】:

  • 过滤器和$scope.thingScope 没有问题,对不起。当您单击过滤器时,它不会显示 Jimmy 数据。它有什么问题?
  • @JoséLezama 输出部分应显示过滤列表部分中的“样式”数组。如果您现在检查它,当您单击 switch 时,过滤后的列表显示三个元素,而输出部分显示两个。这没有按预期工作,因为输出部分是将映射函数应用于过滤范围的结果(应该包含列表中显示的元素)。总而言之,当一个部分有三个元素时,另一个应该也有三个。

标签: angularjs


【解决方案1】:

认为您在视图中的逻辑变得有点繁重并且没有意义,因为视图中绑定的所有内容都在进行观察......如果您改为按程序执行,则更容易解决。

http://plnkr.co/edit/ZExywkLtDxuT82Ud6gYl?p=preview

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="style.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
  </head>

  <body>
    <div ng-controller="myCtrl" ng-app="myApp">

      0. <b>Switch</b>: {{switch}} <br/><br/>
      1. <b>Output</b>: {{thingScope}} <br/><br/>
      2. <b>Filtered List</b>:
      <ul>
        <li ng-repeat="things in filtered">{{things}}</li>
      </ul>
      <a ng-click="changeSwitch(false, '')">unswitch - No Filters</a><br><br>
      <a ng-click="changeSwitch(true, {name:'!Jimmy'})">switch - Not Jimmy</a>
    </div>




    <script type="text/javascript">
      var app = angular.module('myApp', []);
      app.controller('myCtrl', function($scope, $filter) {
        $scope.switch = false;

        // set the default sort type
        $scope.filterType = '';

        var names=[{name:"Johny", styles:["one","two","three"]},{name:"Jimmy", styles:["two","three","four"]},{name:"Kevin", styles:["three","four","five"]}];

            // Option B:
        function filterData(searchObj){
          $scope.filtered = $filter('filter')(names, searchObj);
        };
        filterData();

        $scope.changeSwitch = function(newVal, filterType){
          $scope.switch = newVal;
          filterData(filterType);
          $scope.thingScope = !$scope.switch ? _.map(names,"styles") : _.map($scope.filtered,"styles");
        }

      });
    </script>
  </body>
</html>

【讨论】:

  • 您的解决方案工作正常,但恐怕我需要在视图中使用该逻辑,因为我有更多过滤器应用于该 ng-repeat。无论如何感谢您的方法!
  • @Joe82 你仍然可以将它们移动到一个函数中,但我知道在视图中读取过滤器比 $filter 获取过滤器的方式更容易,也就是说我认为根本问题是$watch 在过滤器之前触发,但两者都是摘要的一部分,只是难以控制视图中所有发生的顺序。
  • 是的,我认为这也是问题所在。我会等待是否有通过修改 $scope.$watch 的替代解决方案,如果没有,我会将其标记为正确。
  • @Joe82 我认为它很好用。这个有什么问题?其他过滤器也会与其他人的名字有关吗?你想按用户过滤吗?还是您有其他自定义过滤器?
  • @JoséLezama 在我的实际应用程序中,我在 ng-repeat 附加了其他 4 个不同的过滤器,并且范围具有更多属性的对象。正如我所说,这个解决方案工作得很好,但我认为我无法将它调整到我拥有的其他过滤器,所以我正在等待是否有人可以以更“角度”的方式解决这个问题。跨度>
【解决方案2】:

好的,我发现了一些问题。

0 - 您正在使用生成的列表元素(已过滤。这是对名称应用过滤器的结果)。当开关改变时,生成的列表并没有完成。所以,你不会找到元素。

1 - 你有很多元素试图在同一个上工作(Swtich/Filter over names)。

2 - 您正在显示使用:$scope.thingScope = $scope.switch ? _.map($scope.names,"styles") : _.map($scope.filtered,"styles"); 因此,当 $scope.switch == true 时,您正在显示 $scope.names。所以错误的条件。

3 - 您首先应用 switch 的更改,然后在 ng-click 中应用 filterType

所以,你可以做两件事。

  1. 在 2 个地方使用重复的过滤器(不推荐。)
  2. ng-repeat 与已处理列表一起使用。并使用控制器中的所有过滤器。正如@shaunhusain 所做的那样。

附:我认为使用活性过滤器可能会更清洁。而不是按名称,请查看此 Plnkr:http://plnkr.co/edit/4uJ5AxP9xntgBe1hQrBW?p=preview

您可以按名称选择(仅单击),但您必须在更新过滤器中再次单击才能应用更改。

【讨论】:

  • 再次感谢您的回答!它对我来说澄清了一点。不过,我会将@shaunhusain 标记为正确,它更直接地回答了暴露的问题。
  • 您可以在其他有关过滤器的问题中查看我的答案。也许它可以帮助你:stackoverflow.com/questions/37661451/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-07
  • 2015-08-09
  • 1970-01-01
相关资源
最近更新 更多