【问题标题】:Global search box in angular角度的全局搜索框
【发布时间】:2013-09-23 15:13:51
【问题描述】:

我想实现一个搜索框,它可以根据使用的控制器更改搜索内容。如果您在“帖子”视图上,它将搜索帖子 api,如果您在视频视图上,它会搜索视频 api。似乎搜索框可能需要自己的控制器。我很确定我需要将搜索服务注入所有模型控制器,但我不确定如何更改它搜索的 url 或将输入绑定到不同的控制器范围。

那么有什么想法可以让一个全局搜索框根据使用它的控制器更改搜索位置并将其状态重新绑定到不断变化的视图中?

【问题讨论】:

    标签: search angularjs service


    【解决方案1】:

    要进行资源调用动态 api,我将首先创建两个 $resources 映射到您的两个端点、帖子和视频。然后在全局搜索中放置一个 ng-change 事件,该事件调用基本控制器中的函数。

    这个函数首先需要弄清楚要搜索什么api。然后进行适当的 api 调用。重要的部分在回调中,我认为这就是您要寻找的。 在回调中,您可以 $broadcast 来自您的 api 查询的 resp 数据。您的每个控制器都将使用 $on 函数监听事件。然后侦听器将使用回调数据填充正确的范围变量。

    下面是伪的。

    与 ng-change 相同的 html 布局

    <html>
    
    <body ng-controller="AppController">
        <form>
            <label>Search</label>
            <input ng-model="global.search" ng-change="apiSearch()" type="text" class="form-control" />
        </form>
    
        <div ui-view="posts">
            <div ng-controller="PostController">
                <p ng-repeat="post in posts | filter: global.search">{{ post.name }}</p>
            </div>
    
        </div>
    
        <div ui-view="videos">
            <div ng-controller="VideoController">
                <p ng-repeat="video in videos | filter: global.search">{{ video.name }}</p>
            </div>
    
        </div>
    
    </body>
    
    </html>
    

    应用控制器

    .controller('AppController', function ($scope, PostService, VideoService) {
    
        $scope.apiSearch = function() {
    
            // Determine what service to use. Could look at the current url. Could set value on scope
            // every time a controller is hit to know what your current controller is. If you need
            // help with this part let me know.
    
            var service = VideoService, eventName = 'video';
            if ($rootScope.currentController == 'PostController') {
                service = PostService;
                eventName = 'post';
            }
    
            // Make call to service, service is either PostService or VideoService, based on your logic above.
            // This is pseudo, i dont know what your call needs to look like.
            service.query({query: $scope.global.search}, function(resp) {
    
                // this is the callback you need to $broadcast the data to the child controllers
               $scope.$broadcast(eventName, resp);
            });
    
    
        }
    
    })
    

    显示结果的每个子控制器。

    .controller('PostController', function($scope) {
    
        // anytime an event is broadcasted with "post" as the key, $scope.posts will be populated with the
        // callback response from your search api.
        $scope.$on('post', function(event, data) {
            $scope.posts = data;
        });
    
    })
    
    .controller('VideoController', function($scope) {
    
        $scope.$on('video', function(event, data) {
            $scope.videos = data;
        });
    
    })
    

    【讨论】:

      【解决方案2】:

      客户端过滤。

      如果您不是在寻找可以通过一种超级简单的方式进行全局搜索来实现的疯狂的东西。我什至不知道这是否可行,所以我只是做了一个快速测试,它确实可以。显然,这可以通过使用服务并在需要的地方注入它们以更详细和可控的方式解决。但是由于我不知道您在寻找什么,所以我将提供此解决方案,如果您喜欢,请接受它。如果您不这样做,我可能会为您提供服务注入解决方案

      快速的解决方案是拥有一个带有 $rootScope ng-model 的应用程序范围的控制器。让我们称之为 global.search。

          $rootScope.global = {
              search: ''
          };
      

      用于应用范围的搜索输入。

      <form>
          <label>Search</label>
          <input ng-model="global.search" type="text" class="form-control" />
      </form>
      

      在单独的部分中,您只需要根据 global.search ng-model 过滤数据。两个例子

      <p ng-repeat="post in posts | filter: global.search">{{ post.name }}</p>
      

      不同范围的第二个模板

      <p ng-repeat="video in videos | filter: global.search">{{ video.name }}</p>
      

      注意它们是如何实现的 |过滤器:global.search。每当 global.search 更改时,当前视图中的任何过滤器都会更改。因此帖子将在帖子视图中过滤,视频在视频视图中。虽然仍然使用相同的 global.search ng-model。

      我对此进行了测试,它确实有效。如果您需要更多详细信息来解释设置和子控制器层次结构,请告诉我。这是一个完整模板的快速浏览

      <html>
      
      <body ng-controller="AppController">
          <form>
              <label>Search</label>
              <input ng-model="global.search" type="text" class="form-control" />
          </form>
      
          <div ui-view="posts">
              <div ng-controller="PostController">
                  <p ng-repeat="post in posts | filter: global.search">{{ post.name }}</p>
              </div>
      
          </div>
      
          <div ui-view="videos">
              <div ng-controller="VideoController">
                  <p ng-repeat="video in videos | filter: global.search">{{ video.name }}</p>
              </div>
      
          </div>
      
      </body>
      
      </html>
      

      【讨论】:

      • 这似乎是一个很好的解决方案。我唯一的问题是,我可以使用过滤器来使用 rest 来访问 rails api 后端吗?
      • 我不使用导轨。我为 REST 服务使用 python 应用程序引擎,为前端使用 Angular,我需要的一切:)。但是,是的,这将与任何休息服务一起使用。调用您的服务器,并使用结果填充 $scope.posts 或 $scope.videos。然后过滤将起作用。当我在发布之前对此进行测试时,它是使用填充我的范围变量的 REST 调用。
      • 我明白你现在所说的流程。我更多地考虑向 REST 后端发送查询并返回分页结果,而不是一次加载所有模型并在客户端过滤它们。
      • 哦,您的意思是您的全局搜索会根据您所在的页面向不同的端点发送请求吗?如果是这样,我很抱歉,我的回答与这样的事情无关。
      • 是的,这就是我所说的
      猜你喜欢
      • 1970-01-01
      • 2021-02-28
      • 2019-12-19
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2011-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多