모델에 숫자를 사용하는 Angularjs ng-options가 초기 값을 선택하지 않습니다.
ng-options를 a와 함께 사용 <select>
하여 숫자 정수 값을 해당 옵션 목록에 바인딩 하려고합니다 . 내 컨트롤러에는 다음과 같은 것이 있습니다.
myApp.controller('MyCtrl', function() {
var self = this;
var unitOptionsFromServer = {
2: "mA",
3: "A",
4: "mV",
5: "V",
6: "W",
7: "kW"
};
self.unitsOptions = Object.keys(unitOptionsFromServer).map(function (key) {
return { id: key, text: unitOptionsFromServer[key] };
});
self.selectedUnitOrdinal = 4; // Assume this value came from the server.
});
HTML :
<div ng-controller="MyCtrl as ctrl">
<div>selectedUnitOrdinal: {{ctrl.selectedUnitOrdinal}}</div>
<select ng-model="ctrl.selectedUnitOrdinal" ng-options="unit.id as unit.text for unit in ctrl.unitsOptions"></select>
</div>
그리고 여기 에 문제를 보여주는 jsFiddle 과 내가 취했지만 만족스럽지 않은 다른 접근 방식이 있습니다.
선택 옵션은이 예제에서 예상 한대로 "mV"대신 빈 값으로 초기화됩니다. 다른 옵션을 선택하면 바인딩이 제대로 작동하는 것 같습니다. selectedUnitOrdinal이 제대로 업데이트됩니다.
초기 모델 값을 숫자 대신 문자열로 설정하면 초기 선택이 작동한다는 것을 알았습니다 (바이올린의 # 3 참조).
ng-options가 숫자 옵션 값으로 잘 작동하기를 바랍니다. 어떻게하면 우아하게 이룰 수 있습니까?
ng-select
지시문에 대한 Angular의 문서는 이 문제를 해결하는 방법을 설명합니다. https://code.angularjs.org/1.4.7/docs/api/ng/directive/select (마지막 섹션)를 참조 하십시오 .
convert-to-number
지시문을 생성 하여 선택 태그에 적용 할 수 있습니다.
JS :
module.directive('convertToNumber', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(val) {
return val != null ? parseInt(val, 10) : null;
});
ngModel.$formatters.push(function(val) {
return val != null ? '' + val : null;
});
}
};
});
HTML :
<select ng-model="model.id" convert-to-number>
<option value="0">Zero</option>
<option value="1">One</option>
<option value="2">Two</option>
</select>
참고 : 문서의 지시문이 null을 처리하지 않기 때문에 약간 조정해야했습니다.
다소 지저분 할 수도 있지만 ng-options에서 특별한 기능 없이도 결과를 얻을 수 있습니다.
<select ng-model="ctrl.selectedUnitOrdinal" ng-options="+(unit.id) as unit.text for unit in ctrl.unitsOptions"></select>
unit.id를 얻을 때 정수가 아닌 문자열을 반환하기 때문입니다. 자바 스크립트의 객체는 키를 문자열로 저장합니다. 따라서이를 수행하는 유일한 방법은 인용문으로 4를 둘러싸는 방법입니다.
편집하다
<select ng-model="ctrl.selectedUnitOrdinal" ng-options="convertToInt(unit.id) as unit.text for unit in ctrl.unitsOptions"></select>
$scope.convertToInt = function(id){
return parseInt(id, 10);
};
You can also define filter number
, this filter will automatically parse string value to int:
<select ng-model="ctrl.selectedUnitOrdinal" ng-options="unit.id|number as unit.text for unit in ctrl.unitsOptions"></select>
angular.module('filters').filter('number', [function() {
return function(input) {
return parseInt(input, 10);
};
}]);
Just to add Christophe's answear: easiest way to achive and maintaint it is to make a directive:
JS:
.directive('convertToNumber', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(val) {
//saves integer to model null as null
return val == null ? null : parseInt(val, 10);
});
ngModel.$formatters.push(function(val) {
//return string for formatter and null as null
return val == null ? null : '' + val ;
});
}
};
});
Christophe's answear wont work correctly for '0' as it returns false on "val?" test.
I think the other solutions are overly complex for simply establishing the value as an integer. I would use:
<select ng-model="model.id">
<option ng-value="{{ 0 }}">Zero</option>
<option ng-value="{{ 1 }}">One</option>
<option ng-value="{{ 2 }}">Two</option>
</select>
Angular is seeing your id
property as a string, add quotes:
self.selectedUnitOrdinal = "4";
Very similarly to tymeJV's answer, simple workaround is to convert the default selection number to a string like this:
self.selectedUnitOrdinal = valueThatCameFromServer.toString();
This way, you don't have to hardcode the number, you can just convert any received value. It's an easy fix without any filters or directives.
<select ng-model="ctrl.selectedUnitOrdinal" ng-options="+(unit.id) as unit.text for unit in ctrl.unitsOptions"></select>
Make id property in unitsOptions as number
self.unitsOptions = Object.keys(unitOptionsFromServer).map(function (key) {
return { id: +key, text: unitOptionsFromServer[key] };
});
While the solution provided by Mathew Berg works it will probably break other selects that use sting-valued select options. This may be a problem if you try to write one universal directive for handling selects (like I did).
A nice workaround is to check if the value is a number (even if it is a string containing a number) and only than do the conversion, like so:
angular.module('<module name>').filter('intToString', [function() {
return function(key) {
return (!isNaN(key)) ? parseInt(key) : key;
};
}]);
or as a controller method:
$scope.intToString = function(key) {
return (!isNaN(key)) ? parseInt(key) : key;
};
'Development Tip' 카테고리의 다른 글
동일한 터미널에서 한 번에 병렬 여러 명령 실행 (0) | 2020.12.02 |
---|---|
Angular : &를 사용하여 지시문 링크 함수 내에서 컨트롤러 함수 호출 (0) | 2020.12.02 |
셸 명령의 출력을 버퍼링 해제하는 방법은 무엇입니까? (0) | 2020.12.02 |
내 앱 내에서 Apple Mail 앱을 시작 하시겠습니까? (0) | 2020.12.02 |
SQLITE 데이터베이스 파일 버전을 찾는 방법 (0) | 2020.12.02 |