angularjs 要从Angular Ui TypeAhead更新的Angular JS力模型

goqiplq2  于 2022-11-28  发布在  Angular
关注(0)|答案(4)|浏览(183)

因此我有一个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;
    });
};

我的输入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">

正如你所看到的,typeahead从getMaterial()读取,我试图在if($stateParams.assetID != undefined)条件中触发它。

预期的工作流程:

1.在url中使用assetID$stateparam导航到此视图。
1.让条件函数看到assetID参数不是undefined,触发GET请求,然后让它返回运行的getMaterial()的结果(第一个GET请求的结果通过getMaterial()自己的GET请求传递-就像第一个GET请求的结果被键入一样)。
1.提前更新模型/类型以在视图中显示getMaterial()值。
我尝试了$scope.$apply(),但是摘要已经在进行中了。我希望有另一个我不知道的快速修复来触发打字。
我也试过这样的办法:
jQuery("input[uib-typeahead]").val(response.data[0].Title).trigger('input');
......但这不是一个好的解决方案,因为我正在键入的一些资产具有完全相同的名称,这就是为什么我试图使用id作为我的url参数,并让typeahead源函数拾取名称,就像它是键入的一样,然后返回到模型的完整对象(名称/id)。
请帮助我实现所需的工作流程。

编辑:Typeahead Source Code

我想激活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()?我如何从我自己的控制器调用它?

uurity8g

uurity8g1#

作为对前面方法的扩展,我将分享另一个解决方案,其中不需要指令。您可以简单地定位input元素并在那里设置view值。
angular.element('#input').controller('ngModel').$setViewValue('');

xbp102n0

xbp102n02#

与html中的getMaterial($viewValue)不同(它将触发每个摘要周期...),您可以连接ng-change,这样只有当数据实际发生更改时才会触发,在这种情况下,您现在拥有一个模型$scope.materials,您可以随时更新它以获取更改。

Java脚本:

$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">
laik7k3q

laik7k3q3#

使用自定义指令:

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

用法:

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

JS系统

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

The DEMO的第一个字符

第一个

p1iqtdky

p1iqtdky4#

另一种方法是挂钩到Typeahead本身,这样,如果它有相同的名称,它将为模型选择正确的对象。
请参阅此处:


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>

相关问题