2

我的 Angular 应用程序中有一个按钮,它将动态地向我的应用程序添加一个输入元素。我想将模型附加到此元素并将其放入监视组以跟踪任何更改。如果用户添加多个输入元素,我想在监视组中添加所有这些模型并跟踪哪个元素改变了它的值。我怎样才能做到这一点?

<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

首先,你打破了 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);
            });
        }
    }
});

然后将新的成绩点指令添加到页面并 $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 回答
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 回答