2013-09-23 81 views
4

我想实现一个搜索框,根据使用哪个控制器来更改它搜索的内容。如果你在“posts”视图中,它将搜索帖子api,如果你在视频视图中,它会搜索视频api。似乎搜索框可能需要自己的控制器。我很确定我需要将搜索服务注入到所有模型控制器中,但我不确定如何更改它搜索的URL或将输入绑定到不同的控制器作用域。角度全局搜索框

因此,任何想法如何拥有一个全球搜索框,它会根据哪个控制器正在使用它并将其状态重新映射到一个不断变化的视图中而改变其搜索位置?

回答

8

来使资源调用动态API我首先创建两个$资源映射到两个端点,帖子和视频。然后在您的全局搜索中添加一个ng-change事件,在您的基础控制器中调用一个函数。

该函数首先需要找出要搜索的API。然后进行适当的api调用。重要的部分是在回调,我认为这是你在找什么。 在回调中,您可以从您的api查询中广播resp数据。您的每个控制器都将使用$ on功能监听事件。监听器将使用回调数据填充正确的范围变量。

Pseudo below。

相同的HTML布局NG-变化

<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> 

AppController的

.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; 
    }); 

}) 
+0

+1:钉住它。谢啦。 –

3

客户端过滤。

如果你不想寻找任何疯狂的事情,可以通过超级简单的方式实现全球搜索。我甚至不知道这是否会起作用,所以我只做了一个快速测试,它确实如此。显然,这可以通过使用服务并在需要的地方注入来更详细和可控地解决。但是因为我不知道你在找什么,我会提供这个解决方案,如果你喜欢它,很好接受它。如果你没有,我可能可以帮助你与服务注入解决方案

快速解决方案是有一个应用程序广泛contoller与$ rootScope ng模型。让我们把它称为global.search。

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

针对应用程序的广泛搜索输入。

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

在单独的部分中,您只需要基于global.search ng模型过滤数据。两个例子

<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> 
+0

这似乎是一个很好的解决方案。我唯一的问题是,我可以使用过滤器来使用rest来打开rails api后端吗? – chris

+0

我不使用铁轨。我使用Python应用引擎进行REST服务,并对前端使用angular,我需要的所有东西:)。但是,这是会与任何休息服务。打电话给你的服务器,并用结果填充$ scope.posts或$ scope.videos。然后过滤将工作。当我在发布之前测试它时,它是用REST调用填充我的范围变量。 –

+0

我收到你现在正在谈论的流程。我正在考虑更多地向REST后端发送查询并返回分页结果,而不是一次加载所有模型并将其过滤到客户端。 – chris