所以我有一个Angular UI Typeahead正在运行,但我有一个用例,我无法让它合作。
我的问题是让它显示一个不是基于用户输入的某个值,这个值有效,但是基于状态。
我正在使用Angular UI Router,因此我的代码如下所示:
if($stateParams.assetID != undefined)
{
$http.get('/getData/idRepo', {
params: {
id: $stateParams.assetID
}
}).then(function(response){
$scope.getMaterial(response.data[0].Title);
//this is where I try and trigger the getMaterial
//function to show the Typeahead value based on a url parameter
//
});
}
$scope.getMaterial = function(val) {
return $http.get($scope.material[0].Query, {
params: {
title: val
}
}).then(function(response){
return response.data;
});
};
我的Typeahead HTML是这样的:
<input type="text" ng-model="selected.asyncSelected"
placeholder="Material Name..."
uib-typeahead="med as med.name for med in getMaterial($viewValue)"
typeahead-editable="false"
typeahead-template-url="meditationssearch.html"
typeahead-select-on-exact="true"
typeahead-select-on-exact="true"
typeahead-loading="loadingLocations"
typeahead-no-results="noResults"
class="form-control">
正如您所看到的,输入内容从getMaterial()
读取,我尝试在if($stateParams.assetID != undefined)
条件中触发。
预期的工作流程
$stateparam
导航到此视图,其中包含网址中的assetID
。assetID
param未定义,触发GET请求然后让它返回正在运行的getMaterial()
的结果(第一个GET请求的结果通过getMaterial传递( )拥有GET请求 - 就像输入第一个GET请求的结果一样。)getMaterial()
值。我尝试$scope.$apply()
,但摘要已在进行中。我希望有另一个快速解决方案,我只是不知道触发预先输入。
我也试过这样的事情:
jQuery("input[uib-typeahead]").val(response.data[0].Title).trigger('input');
...但这不是一个好的解决方案,因为我输入的某些资产具有完全相同的名称,这就是我尝试使用id
作为我的url参数的原因并使用typeahead源函数获取名称,就好像它已输入,然后返回到模型的完整对象(名称/ id)。
请帮助我实现我想要的工作流程。
我相信我想在select函数中激活一些东西:
scope.select = function(activeIdx, evt) {
//called from within the $digest() cycle
var locals = {};
var model, item;
selected = true;
locals[parserResult.itemName] = item = scope.matches[activeIdx].model;
model = parserResult.modelMapper(originalScope, locals);
$setModelValue(originalScope, model);
modelCtrl.$setValidity('editable', true);
modelCtrl.$setValidity('parse', true);
onSelectCallback(originalScope, {
$item: item,
$model: model,
$label: parserResult.viewMapper(originalScope, locals),
$event: evt
});
resetMatches();
//return focus to the input element if a match was selected via a mouse click event
// use timeout to avoid $rootScope:inprog error
if (scope.$eval(attrs.typeaheadFocusOnSelect) !== false) {
$timeout(function() { element[0].focus(); }, 0, false);
}
};
也许resetMatches()
?如何从我自己的控制器中调用它?
答案 0 :(得分:0)
而不是在html中使用getMaterial($viewValue)
(这将触发每个摘要周期......),您可以将ng-change连接起来,而这种方式只会在数据实际发生变化时触发。在这种情况下,您现在有一个模型$scope.materials
,您可以随时更新。
<强>的javascript:强>
$scope.modelChanged = function(){
$http.get($scope.material[0].Query, {
params: {
title: $scope.selected.asyncSelected
}
}).then(function (response) {
$scope.materials = response.data;
});
}
if ($stateParams.assetID != undefined) {
$http.get('/getData/idRepo', {
params: {
id: $stateParams.assetID
}
}).then(function (response) {
$scope.selected.asyncSelected = response.data[0].Title;
$scope.modelChanged(); //not sure if you have to run this it might fire automatically
});
}
<强> HTML:强>
<input type="text" ng-model="selected.asyncSelected"
placeholder="Material Name..."
uib-typeahead="material as material.name for material in materials"
typeahead-editable="false"
typeahead-template-url="meditationssearch.html"
typeahead-select-on-exact="true"
typeahead-select-on-exact="true"
typeahead-loading="loadingLocations"
typeahead-no-results="noResults"
ng-change="modelChanged()"
class="form-control">
答案 1 :(得分:0)
使用自定义指令:
<input type="text" ng-model="selected.asyncSelected"
force-input="{{forceValue}}"
placeholder="Material Name..."
uib-typeahead="med as med.name for med in getMaterial($viewValue)"
typeahead-editable="false"
typeahead-template-url="meditationssearch.html"
typeahead-select-on-exact="true"
typeahead-select-on-exact="true"
typeahead-loading="loadingLocations"
typeahead-no-results="noResults"
class="form-control">
用法:
if($stateParams.assetID != undefined)
{
$http.get('/getData/idRepo', {
params: {
id: $stateParams.assetID
}
}).then(function(response){
̶$̶s̶c̶o̶p̶e̶.̶g̶e̶t̶M̶a̶t̶e̶r̶i̶a̶l̶(̶r̶e̶s̶p̶o̶n̶s̶e̶.̶d̶a̶t̶a̶[̶0̶]̶.̶T̶i̶t̶l̶e̶)̶;̶
$scope.forceValue = response.data[0].Title;
//this is where I try and trigger the getMaterial
//function to show the Typeahead value based on a url parameter
//
});
}
JS
angular.module('app', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('app').controller('ctrl', function($scope, $http) {
var _selected;
$scope.selected = undefined;
$scope.states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia',
'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas',
'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts',
'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana',
'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico',
'New York', 'North Dakota', 'North Carolina', 'Ohio', 'Oklahoma',
'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina',
'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia',
'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'];
});
angular.module('app').directive("forceInput", function() {
return {
require: "ngModel",
link: postLink
}
function postLink(scope, elem, attrs, ngModel) {
attrs.$observe('forceInput', function(value) {
if (!value) return;
elem[0].value = value;
ngModel.$setViewValue(value);
})
}
})
<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/angular-animate/angular-animate.js"></script>
<script src="//unpkg.com/angular-sanitize/angular-sanitize.js"></script>
<script src="//unpkg.com/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js"></script>
<link href="//unpkg.com/bootstrap@3.3/dist/css/bootstrap.css" rel="stylesheet">
<body ng-app="app">
<div class='container-fluid typeahead-demo' ng-controller="ctrl">
<pre>Model: {{selected | json}}</pre>
<input type="text" ng-model="selected"
force-input="a"
uib-typeahead="state for state in states | filter:$viewValue | limitTo:8"
class="form-control">
</div>
</body>
lib
答案 2 :(得分:-1)
另一种方法是挂钩到Typeahead本身,这样如果它具有相同的名称,它将为模型选择正确的对象。
见这里:
<强> https://plnkr.co/edit/ABM72yyV4dtp5PsH4bIm?p=preview 强>
angular.module('ui.bootstrap.demo').controller('TypeaheadCtrl', function($scope, $http,uibTypeaheadParser) {
$scope.fire = function(val){
var locals = {};
var model;
var parserResult = uibTypeaheadParser.parse(angular.element("input[uib-typeahead]")[0].getAttribute('uib-typeahead'));
locals[parserResult.itemName] = val;
model = parserResult.modelMapper($scope, locals);
console.log(model);
$scope.customSelected = model; //$scope.customSelected is the ng-model in this example
}
});
其中val
是一个对象,而不是一个字符串。
<button ng-click="fire({
'name': 'Minnesota',
'flag': 'b/b9/Flag_of_Minnesota.svg/46px-Flag_of_Minnesota.svg.png'
})" class="button btn-primary">CLICK ME TO SET TYPEAHEAD</button>