目前我有三个输入需要使用自动完成,看起来像这样:
<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>