5

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

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

4

2 回答 2

9

要进行资源调用动态 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;
    });

})
于 2013-09-23T19:17:49.100 回答
3

客户端过滤。

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

快速的解决方案是拥有一个带有 $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>
于 2013-09-23T16:00:10.317 回答