如何以解耦的方式将自动完成/前瞻指令用于使用单独服务的多个单独输入



目前我有三个输入需要使用自动完成,看起来像这样:

<div class="actor-container">
   <input type="text" class="actors"/> 
</div>
<div class="movie-container">
   <input type="text" class="movies"/> 
</div>
<div class="director-container">
   <input type="text" class="directors"/> 
</div>

我也有自己的自动完成指令

<div my-autocomplete="my-autocomplete" service="serviceName"></div>

自动完成是获取serviceName作为输入,以使用$injector 访问不同的数据存储库(在不同的池中搜索)

将此指令与其他三个输入连接起来的最佳AngularJS实践是什么?我想把它放在每个输入中,就像这样:

<div class="actor-container">
   <input type="text" class="actors" my-autocomplete="my-autocomplete" service="actorService"/> 
</div>
<div class="movie-container">
   <input type="text" class="movies" my-autocomplete="my-autocomplete" service="movieService"/> 
</div>
<div class="director-container">
   <input type="text" class="directors"  my-autocomplete="my-autocomplete" service="directorService"/> 
</div>

但这种做法好吗?或者指令应该放在"外部"一次,然后使用共享服务/广播/手表等,使用三个单独的控制器与三个输入中的每一个进行通信?

<div class="actor-container" ng-controller="addActorCtrl">
   <input type="text" class="actors"/> 
</div>
<div class="movie-container" ng-controller="addMovieCtrl">
   <input type="text" class="movies"/> 
</div>
<div class="director-container" ng-controller="addDirectorCtrl">
   <input type="text" class="directors"/> 
</div>
<div my-autocomplete="my-autocomplete" service="serviceName(how to pass that??)"></div>

应该发生的是,有人应该键入这些字段中的每一个,并根据serviceName和用户输入的内容弹出相应的自动完成。然后,用户将单击其中一个返回的条目,该条目应添加到右侧容器中。我还想知道代码对象.movies.push()(例如,当用户单击建议的电影时,用于电影)将被放置在哪里。。

如果你能提供一个带有一些代码的例子,我将不胜感激,因为我是AngularJS的新手,我认为这对其他人也很有用:)

感谢

这就是我所做的,我认为这是一个很好的实践:

我为每个输入都有一个控制器,并在每个输入中添加指令:

<div ng-controller="addActorCtrl">
     <div suggest-dir="suggest-dir" service="actorService" input-string="{{input1}}" select="addActor(suggestEntry)"></div>
     <input id="actors" name="actors" type="text"  placeholder="" class="input-medium" ng-model="input1"/>
</div>
<div ng-controller="addMovieCtrl">
     <div suggest-dir="suggest-dir" service="movieService" input-string="{{input2}}" select="addMovie(suggestEntry)"></div>
     <input id="actors" name="actors" type="text"  placeholder="" class="input-medium" ng-model="input2"/>
</div>
<div ng-controller="addDirectorCtrl">
     <div suggest-dir="suggest-dir" service="directorService" input-string="{{input3}}" select="addDirector(suggestEntry)"></div>
     <input id="actors" name="actors" type="text"  placeholder="" class="input-medium" ng-model="inpu23"/>
</div>

这是我的自动完成指令

angular.
module('myApp.suggestModule').
directive('suggestDir',function(){
    // Runs during compile
    return {
        scope: {
            inputString: '@',
            service: '@',
            select: '&'
        },
        controller: [
            '$scope',
            '$injector', 
            function($scope, $injector) {
                this.inputChanged = function(inputString){
                    $injector.get($scope.service).suggest(inputString,
                        function(data){
                            $scope.suggestEntries = data;
                        }
                    );
                };
                this.entryWasClicked = function(suggestEntry){
                    $scope.select({suggestEntry:suggestEntry})
                }
        }],
        restrict: 'A',
        templateUrl: 'suggestMenu/views/suggest-menu.html',
        link: function(scope, element, attrs, controller) {
            scope.$watch('inputString', function(newValue, oldValue) {
                controller.inputChanged(newValue);
            });

        }
    };
})

这是我的自动完成条目指令,当单击它时,它将从其父suggestDir调用entryWasClicked。它的父级调用$scope.select,但它是一个&参数,因此它是在<div suggest-dir select="functionToBeCalled/> 中传递的函数

directive('suggestEntryDir',function(){
        // Runs during compile
        return {
            require: '^suggestDir',
            restrict: 'A',
            templateUrl: 'suggestMenu/views/suggest-entry.html',
            link: function(scope, element, attrs, controller) {
                var suggestEntry = scope.$eval(attrs.suggestEntry);
                element.bind('click', function(e){
                    scope.$apply(function(){ controller.entryWasClicked(suggestEntry)})
                });
            }
        };
    });

这是一个包装器控制器(我用于每个输入),所以一切都是解耦的:

controller('addActorCtrl',[
    '$scope',
    function($scope){
      var obj= $scope.obj;
        $scope.addActor= function (actor){
                if(!obj.actors){
                    obj.actors = [];
                }
                obj.actors.push(actors);   
            };
    }]);

这是其中一个服务(actorService)。服务从数据库中获取数据,并表现为存储库:

angular.
    module('myApp.actorModule').
    constant('restAPI','http://localhost/project/').
    factory('actorService',['$http','restAPI',function($http,restAPI){
        return {
            latest: function (callback){
                $http({
                    method: 'GET',
                    url: '',
                    cache: true
                }).success(callback);
            },
            find: function(id, callback){
                $http({
                    method: 'GET',
                    url: restAPI+'actor/'+id,
                    cache: true
                }).success(callback);
            },
            suggest: function(stringInput,callback){
                $http({
                    method: 'GET',
                    url: restAPI+'actor/suggest/'+stringInput,
                    cache: true
                }).success(callback);
            },
            update: function(id,actor, callback){
                $http({
                    method: 'PUT',
                    url: restAPI+'actor/'+id,
                    data: actor
                }).success(callback);
            }
        }
    }])

最后,这是我的建议指令的模板:

<div id="suggestions" ng-show="suggestEntries.length>0 && inputString.length>0">
<div class="scrollbar"><div class="track"><div class="thumb"><div class="end"></div></div></div></div>
<div class="viewport">
    <div id="suggestions-list" class="overview">
        <div class="types" ng-repeat="suggestEntry in suggestEntries">
            <div suggest-entry-dir="suggest-entry-dir" suggest-entry="suggestEntry"></div>
        </div>
    </div>
</div>
<div class="close" style="width:10px; cursor: pointer; height:10px; background-color:#aaaaff; position:absolute; top: 4px; right: 4px;"></div>
</div>

这是建议进入

<div class="suggest-entry  suggest-{{suggestEntry.label}}">
    {{suggestEntry.textIndexed}}
</div>

最新更新