JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://rawgit.com/rkrdovrgs/angular-fluent-validation/master/ng-fluent-validation.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<section ng-app="sampleMod">
    <div ng-controller="mainController as mn">
        <label>Name:</label>        
        <input ng-model="mn.newStudent.Name" type="text"/>
        <i ng-validation-icon="mn.newStudent.$errors.Name"><label></label></i>
        <br/>
        <br/>
        <label>Age:</label>
        <input ng-model="mn.newStudent.Age" type="text"/>
        <i ng-validation-icon="mn.newStudent.$errors.Age"><label></label></i>
        <br/>
        <br/>
        <label>Is full time student?</label>
        <input ng-model="mn.newStudent.IsFullTime" type="checkbox"/>
        <br/>
        <br/>
        <label>Number of credits:</label>
        <input ng-model="mn.newStudent.NumberOfCredits" type="text"/>
        <i ng-validation-icon="mn.newStudent.$errors.NumberOfCredits"><label></label></i>
        <br/>
        <br/>
       
        <ul>
            <li><input type="button" value="Add Address" ng-click="mn.addAddress()" />
            <i ng-validation-icon="mn.newStudent.$errors.Addresses"><label></label></i>
            </li>
            <li ng-repeat="adr in mn.newStudent.Addresses">
                Address line: <input type="text" ng-model="adr.AddressLine"/>
                <i ng-validation-icon="adr.$errors.AddressLine"><label></label></i>
                Zipcode: <input type="text" ng-model="adr.Zipcode"/>
                <i ng-validation-icon="adr.$errors.Zipcode"><label></label></i>
            </li>
        </ul>        
        <br/>
        
        <input type="button" value="Save" ng-click="mn.save()" />
        <br/>
        <ul>
            <li ng-repeat="err in mn.valResult.errors">{{ err.propertyName }}: {{ err.errorMessage }}</li>
        </ul>
        
    </div>
</section>

JavaScript

var mod = angular.module('sampleMod', ['ngFluentValidation']);

mod.factory('models', function(){
    var models = {};
    models.Student = function(){
        this.Name = null;
        this.Age = null;
        this.IsFullTime = true;
        this.NumberOfCredits = 0;
        this.Addresses = [];
        
    };
    
    models.Address = function(){        
        this.AddressLine = null;
        this.Zipcode = null;
    };
    
    return models;
});

mod.factory('studentValidator', function(validator, addressValidator){
    var studentValidator = s = new validator();
    
    s.ruleFor('Name').notEmpty();
    s.ruleFor('Name').length(3);
    s.ruleFor('Age').greaterThan(17);
    
    s.ruleFor('Addresses').notEmpty();
    s.ruleFor('Addresses').setCollectionValidator(addressValidator).withMessage('Invalid Addresses');
   
    s.ruleFor('NumberOfCredits').greaterThanOrEqual(12).when(studentIsEnrolledFullTime);
    s.ruleFor('NumberOfCredits').lessThanOrEqual(18);
    
    function studentIsEnrolledFullTime(student){
        return student.IsFullTime;
    }
    
    return studentValidator;
});

mod.factory('addressValidator', function(validator){
    var addressValidator = s = new validator();
    
    s.ruleFor('AddressLine').notEmpty();
    s.ruleFor('Zipcode').length(5);
    
    
    return addressValidator;
});

mod.controller('mainController', function(models, studentValidator, $scope){
    var vm = this;
    
    vm.valResult = {};
    
    vm.newStudent = new models.Student();
    
    vm.addAddress = function(){
        vm.newStudent.Addresses.push(new models.Address());
    }
   
    vm.save = function(){
        var unregisterValidatorWatch =         
            $scope.$watch(function(){return vm.newStudent;},
                         function(){                          
                             vm.valResult = studentValidator.validate(vm.newStudent); 
                             if(vm.newStudent.$isValid)
                                ...