AngularJS 字符串输入 ngModel.



我正在从JSON文件导入标签/输入信息,以尝试减小HTML的大小,并使将来更容易修改。部分这意味着我正在使用 ngModel 的字符串输入。

问题在于双向绑定未按预期运行。我已经看到一些使用指令来帮助解决这个问题的线程,但我无法让它工作。

小提琴示例:http://jsfiddle.net/kelh/LLuwka8h/


编辑:小提琴示例更新:http://jsfiddle.net/kelh/6vccr206/

当将选择标签从"first"更改为"second"时,修改第二个文本框(字符串输入(将不会绑定到num2的正确值,而是会修改num1。


JS代码:

var app = angular.module('myApp',[]);
app.controller('MyCtrl', ['$scope',  function($scope) 
{
        $scope.calc = {num1:100, num2:350};
    $scope.num1 = 100;
    $scope.num2 = 350;
    $scope.labels = {
        selected: null,
      options: [
        {id: 0, name: 'first'},
        {id: 1, name: 'second'}
      ]
    };
    $scope.labels.selected = $scope.labels.options[0];
    $scope.itemsPlaceholder = [{"label":"First One", "model":"calc.num1"}, {"label":"Second one", "model":"calc.num2"}];
    $scope.items = [$scope.itemsPlaceholder[0]];
    $scope.change = function()
    {
        var id = $scope.labels.selected.id;
        $scope.items = [$scope.itemsPlaceholder[id]];
    }
}]);
app.directive('ngBindModel',function($compile){
    return {             
        link: function(scope,element,attr){
            element[0].removeAttribute('ng-bind-model');
            element[0].setAttribute('ng-model',scope.$eval(attr.ngBindModel));
            $compile(element[0])(scope);
        }
    };
});
app.directive('stringToNumber', function($compile) {
    return {
        require: 'ngModel',           
        link: function(scope, element, attrs, ngModel) {
            /*
            ngModel.$parsers.push(function(value) {
                return '' + value;
            });
            //*/
            ngModel.$formatters.push(function(value) {
                return parseFloat(value);
            });
        }
    };
});

.HTML:

<div ng-app="myApp" ng-controller="MyCtrl">
  num1: {{calc.num1}} <br> num2: {{calc.num2}}
  <br><BR>
  {{labels.selected.options.id}}
  <label>Select: </label>
  <select ng-model="labels.selected" ng-options="options.name for options in labels.options track by options.id" ng-change="change();">
  </select>
  <BR><BR><BR>
  <i> "normal" usage of ngModel -- </i>
  <div ng-show="labels.selected.id == 0">
    <label>{{items[0].label}}  (model is: num1) </label><br>
    <input type="number" name="inp{{$index}}" ng-model="calc.num1"/>
  </div>
  <div ng-show="labels.selected.id == 1">
    <label>{{items[1].label}}  (model is: num2) </label><br>
    <input type="number" name="inp{{$index}}" ng-model="calc.num2"/>
  </div>
  <br> <i> string input for ngModel -- </i>
  <div ng-repeat="item in items track by $index">
    <label>{{item.label}}  (model is: {{item.model}}) </label><br>
    <input type="number" name="inp{{$index}}"
      string-to-number ng-model="this[item.model]" ng-bind-model="item.model" />
  </div>
</div>

我通过使用括号表示法来访问 JS 对象属性来解决这个问题。我的最终目标是将其用于嵌套属性。

.JS:

var app = angular.module('myApp',[]);
app.controller('MyCtrl', ['$scope',  function($scope) 
{
        $scope.calc = {num1:100, num2:350};
    $scope.num1 = 100;
    $scope.num2 = 350;
    $scope.labels = {
        selected: null,
      options: [
        {id: 0, name: 'first'},
        {id: 1, name: 'second'}
      ]
    };
    $scope.labels.selected = $scope.labels.options[0];
    $scope.itemsPlaceholder = [{"label":"First One", "model":"num1"}, {"label":"Second one", "model":"num2"}];
    $scope.items = [$scope.itemsPlaceholder[0]];
    $scope.change = function()
    {
        var id = $scope.labels.selected.id;
        $scope.items = [$scope.itemsPlaceholder[id]];
    }
}]);
app.directive('ngBindModel',function($compile){
    return {             
        link: function(scope,element,attr){
            element[0].removeAttribute('ng-bind-model');
            element[0].setAttribute('ng-model',scope.$eval(attr.ngBindModel));
            $compile(element[0])(scope);
        }
    };
});
app.directive('stringToNumber', function($compile) {
    return {
        require: 'ngModel',           
        link: function(scope, element, attrs, ngModel) {
            /*
            ngModel.$parsers.push(function(value) {
                return '' + value;
            });
            //*/
            ngModel.$formatters.push(function(value) {
                return parseFloat(value);
            });
        }
    };
});

.HTML:

<div ng-app="myApp" ng-controller="MyCtrl">
  num1: {{calc.num1}} <br> num2: {{calc.num2}}
  <br><BR>
  {{labels.selected.options.id}}
  <label>Select: </label>
  <select ng-model="labels.selected" ng-options="options.name for options in labels.options track by options.id" ng-change="change();">
  </select>
  <BR><BR><BR>
  <i> "normal" usage of ngModel -- </i>
  <div ng-show="labels.selected.id == 0">
    <label>{{items[0].label}}  (model is: num1) </label><br>
    <input type="number" name="inp{{$index}}" ng-model="calc.num1"/>
  </div>
  <div ng-show="labels.selected.id == 1">
    <label>{{items[1].label}}  (model is: num2) </label><br>
    <input type="number" name="inp{{$index}}" ng-model="calc.num2"/>
  </div>
  <br> <i> string input for ngModel -- </i>
  <div ng-repeat="item in items track by $index">
    <label>{{item.label}}  (model is: {{item.model}}) </label><br>
    <input type="number" name="inp{{$index}}"
       ng-model="calc[item.model]" />
  </div>
</div>

最新更新