2

アプリに入力要素を動的に追加するボタンがアプリにありました。モデルをこの要素にアタッチし、変更を追跡するためにウォッチ グループに配置します。ユーザーが複数の入力要素を追加する場合、それらすべてのモデルをウォッチ グループに追加し、どの要素がその値を変更したかを追跡します。これどうやってするの?

<body ng-app="myApp">

<div ng-controller="GpaController" > 
<form id="mform">
 <select name="grade" ng-model="grade" ng-options="key as key for (key,value) in gradePoints" ></select>    
<input type="number" min="1" max="4" ng-model="score">

</form>
<button type="button" ng-click="addElement()">Add</button>

</div>
<script type="text/javascript" src="./app/angular.min.js"></script>
<script type="text/javascript" src="./app/jquery-2.1.3.min.js"></script>
<script type="text/javascript">

angular.module('myApp', [])
.controller('GpaController', ['$scope', '$compile', function($scope, $compile){
    $scope.grade = 'A';
    $scope.score = 4;
    var gradePoints = { 'A': 4, 'A-': 3.7, 
                   'B+': 3.3, 'B': 3.0, 'B-': 2.7, 
                   'C+': 2.3, 'C': 2.0, 'C-': 1.7, 
                   'D': 1, 'F': 0 };
    $scope.gradePoints = gradePoints;
            $scope.$watchGroup(['grade', 'score'], function(){
                console.log($scope.grade)
                var n = $scope.gradePoints[$scope.grade] * $scope.score;
                    console.log(n);
            });
            $scope.addElement = function(){
                var val = '<div><select name="grade" ng-model="grade" ng-  options="key as key for (key, value) in gradePoints" > </select><input type="number" min="1" max="4" ng-model="score"><div>';
                var ele = $compile(val)($scope);
                    $("#mform").append(ele);
            }

}]);
</script>
</body>
4

2 に答える 2

1

以下の方法で、どの変数が変更されたかを確認できます。

$scope.$watchGroup(['grade', 'score'],
  function(newVal, oldVal) {
    var changed = ''
    if (newVal[0] != oldVal[0])
        changed = 'grade';
    if (newVal[1] != oldVal[1])
        changed = 'score';
});

詳細については、このSO Answerを参照してください。

アップデート

新しい値を追加するには、要素を追加する代わりに ng-repeat を使用できます

マークアップ

<form id="mform">
    <div ng-repeat="obj in objects">
        <select name="grade" ng-model="grade[obj]" 
         ng-options="key as key for (key,value) in gradePoints">
        </select>
        <input type="number" min="1" max="4" ng-model="score" />
    <div>
</form>

コントローラ

$scope.objects = ["1"]; //i have given sample, you could try something like this.
$scope.addElement = function(){ 
  $scope.objects.push($scope.objects.length + 1) 
}
于 2015-04-23T15:26:15.917 に答える
1

まず、Angular の #1 ルールを破っています。ディレクティブに属するコントローラーでは、DOM 操作または要素ルックアップを行うことはできません。

実際、コントローラー内のすべてのロジックは、実際にはディレクティブに属しています。

.directive('gradePoints', function($parse) {
    return {
        template: function($element, $attrs) {
            return '<div><select name="grade" ng-model="' + $attrs.ngModel + '.grade" ng-options="key as key for (key, value) in gradePoints" > </select><input type="number" min="1" max="4" ng-model="' + $attrs.ngModel + '.score"> <div>',
        }
        link: function(scope, element, attrs) {
            $scope.grade = 'A';
            $scope.score = 4;
            var gradePoints = { 'A': 4, 'A-': 3.7, 
            'B+': 3.3, 'B': 3.0, 'B-': 2.7, 
            'C+': 2.3, 'C': 2.0, 'C-': 1.7, 
            'D': 1, 'F': 0 };

            $scope.$watchGroup(['grade', 'score'], function(){
                console.log($scope.grade)
                var n = $scope.gradePoints[$scope.grade] * $scope.score;
                console.log(n);
            });
        }
    }
});

次に、新しい grade-points ディレクティブをページに追加し、それらを $compile します。

このディレクティブをページに追加する方法に関する質問への回答:

これには複数の方法がありますが、おそらくより簡単なのは、ディレクティブを ng-repeat に配置し、コントローラーがグレードの配列に新しいエントリを追加することです。

コントローラーで:

$scope.rows = [];
$scope.addRow = function() {
    $scope.rows.push({});
}

HTML の場合:

<button ng-click="addRow()"/>
<div ng-repeat="row in rows">
    <grade-point ng-model="row"/>
</div>
于 2015-04-23T15:28:30.473 に答える