2017-06-14 82 views
0

我正在從JSON文件導入標籤/輸入信息,以嘗試減小HTML的大小並使其在未來更容易修改。其中的一部分意味着我使用ngModel的字符串輸入。ngModel的AngularJS字符串輸入

麻煩在於雙向綁定不能按預期行事。我已經看到了一些線程,其中使用了指令來幫助解決這個問題,但是我無法實現它。

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


編輯:小提琴例如更新:http://jsfiddle.net/kelh/6vccr206/

當從 「第一」 到 「第二」 改變選擇標籤,修改所述第二文本框(字符串輸入)不會被綁定到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> 

回答

0

我計算出來,通過使用括號標記用於訪問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>