AngularJS $ setPristine与TypeScript:form是未定义的

时间:2014-04-27 11:16:51

标签: angularjs validation typescript

当我尝试使用TypeScript中的form.$setPristine时,它不起作用,调试说form未定义。根据我的阅读,$scope.formName.$setPristine()将形式设置为原始形式。要从控制器访问$scope.formName,我将其作为ng.IFormController属性添加到我的自定义范围界面。但是,当我致电$scope.form.$setPristine()时,它无法正常工作,调试节目$scope.form未定义。

打字稿:

interface IMyScope extends ng.IScope {
    employees: Array<IEmployee>;
    employeeToAdd: IEmployee;
    addEmployee(): void;
    form: ng.IFormController;
}

class EmployeeAddController {
    static $inject = ['$scope', 'Employees'];

    constructor(
        $scope: IMyScope,
        $modalInstance: ng.ui.bootstrap.IModalServiceInstance,  
        Employees: IUpdateableResourceClass<IUpdateableResource>
    ) {
        $scope.employees = new Array<IEmployee>();

        $scope.employeeToAdd = {
            Name: '',
            Email: ''
        };

        $scope.addEmployee = function () {
            Employees.save(null, $scope.employeeToAdd, function (employee: IEmployee) {
                $scope.employees.push(employee);
                $scope.employeeToAdd.Email = '';
            $scope.employeeToAdd.Name = '';
                $scope.form.$setPristine(); // $scope.form is undefined
            });
        };
    }
} 

HTML:

<form role="form" class="form-inline" name="form">
    <div class="form-group" ng-class="{ 'has-error': form.name.$dirty && form.name.$invalid }">
        <input type="text" class="form-control" ng-model="employeeToAdd.Name" name="name" required>
    </div>
    <div class="form-group" ng-class="{ 'has-error': form.email.$dirty && form.email.$invalid }">
        <input type="email" class="form-control" ng-model="employeeToAdd.Email" name="email" required>
    </div>
    <button type="button" class="btn btn-default" ng-click="addEmployee()" ng-disabled="form.$invalid">Add</button>
</form>

4 个答案:

答案 0 :(得分:6)

我在使用表单的应用程序中所做的是将表单对象传递给清除它的方法,而不是直接处理范围。

<button data-ng-click="clearAndResetForm(Form)"></button>

$scope.clearAndResetForm = (form:ng.IFormController)=> {
   this.clearAndResetForm(form);
};


private clearAndResetForm(form:ng.IFormController) {
   this.$scope.fieldOne = undefined;
   this.$scope.fieldTwo = undefined;
   form.$setPristine();
}

我不完全确定为什么我的代码可以工作而你的代码没有。但希望这种方法可以帮助你。

答案 1 :(得分:4)

虽然Sobieck00的解决方案也有效,但感谢stevuu的建议,我已经调试了它并找到了一种方法来实现它而无需传递表单引用。可以form访问$scope.$$childTail.form

interface IMyScope extends ng.IScope {
    employees: Array<IEmployee>;
    employeeToAdd: IEmployee;
    addEmployee(): void;
    $$childTail: any; // Add this to access $$childTail in current scope
}

然后在$scope.addEmployee()中将其重置为:

$scope.$$childTail.form.$setPristine();

答案 2 :(得分:1)

我遇到了类似的问题并且问题出现了,因为<form>标签位于视图中而不是模板中。例如;

&#13;
&#13;
<!-- This was in the template -->
<div class='container-fluid body-content'>
    <ng-view>

    </ng-view>
</div>

<!-- And this was in the view -->
<form id="frmSection" name="frmSection" role="form" class="form" novalidate>
  .
  .
  .
</form>  
&#13;
&#13;
&#13;

我把它改成了;

&#13;
&#13;
<-- Template -->
<div class="container-fluid body-content">
  <form id="frmSection" name="frmSection" role="form" class="form" novalidate>
    <ng-view>

    </ng-view>
  </form>
</div>

<-- View -->
<fieldset>
     <legend>Report Text</legend>

    <div class="form-group">
      .
      .
      .
    </div>
</fieldset>
&#13;
&#13;
&#13;

$scope.frmSection.$setPristine();行按预期工作。

答案 3 :(得分:-1)

其他答案可能有效,但似乎它们过于复杂。如果您使用“controller as”,您可以根据别名为表单指定名称并使用它完成。

看一下下面的例子。我只是将表单命名为我的控制器上的属性,然后从JavaScript中可以看到我可以直接通过名称引用它。没有技巧,噱头或奇怪的工作,不需要依赖@ISA

$scope
(function (app) {
    
    function ctrl() {
    }
    
    angular.extend(ctrl.prototype, {
        email: '',
        submit: function () {
            if (this.ctrlForm.email.$invalid) {
                alert("Invalid email!");
                return;
            }
            alert("Submitted " + this.email);
            this.email = '';
            this.ctrlForm.$setPristine();
        }
    });
    
    app.controller("formCtrl", ctrl);
    
})(angular.module("formExample",[]));

请注意,<script src="https://code.angularjs.org/1.3.9/angular.min.js"></script> <div ng-app="formExample" ng-controller="formCtrl as ctrl"> <form name="ctrl.ctrlForm" role="form" novalidate=""> <input name="email" type="email" required="" ng-model="ctrl.email" placeholder="Enter a valid email."/> <div ng-if="ctrl.ctrlForm.email.$invalid">Email is invalid!</div> <button ng-click="ctrl.submit()" ng-disabled="ctrl.ctrlForm.$invalid || ctrl.ctrlForm.$pristine">Submit</button> </form> </div>是我注册控制器的名称,而formCtrl是我的控制器的别名(有些人可能更喜欢ctrl,所以我将表单命名为{{1}这就是我在HTML中引用它的方式。然后控制器获取该属性,因此它被简单地引用为vm

同样作为小提琴:http://jsfiddle.net/jeremylikness/du5ptxyc/