Knockout Editor Pattern with Validation

HTML

<script src="https://rawgit.com/ericmbarnard/Knockout-Validation/master/Src/knockout.validation.js"></script>
<p>Select "Location1" and change the name to "Location2". It will become invalid.</p>
<p>Now change that same field back to "Location1". It should be valid but is still marked invalid</p>
<hr>
<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>State</th>
            <th>Headline</th>
            <th>Type</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: locations">
        <tr data-bind="click: $root.edit">
            <td data-bind="text: name"></td>
            <td data-bind="text: state"></td>
            <td data-bind="text: headline"></td>
            <td data-bind="text: type().name"></td>
        </tr>
    </tbody>
</table>

<div class="edit-form" data-bind="visible: selectedLocationForEditing, with: selectedLocationForEditing">
    <p>Edit Selected Record</p>
    Errors: <span data-bind="text: errors().length"></span>
    <div>
        <label>Id</label>
        <span data-bind="text: id"></span>
    </div>
    <div>
        <label>Name</label>
        <input type="text" data-bind="value: name"></input>
    </div>
    <div>
        <label>State</label>
        <input type="text" data-bind="value: state"></input>
    </div>
    <div>
        <label>Headline</label>
        <input type="text" data-bind="value: headline"></input>
    </div>
    <div>
        <label>Type</label>
        <select data-bind="options: $root.types, optionsText: 'name', value: type, optionsCaption: 'Choose...'"></select>
    </div>
    <a data-bind="click: $root.update">Update</a>
    <a data-bind="click: $root.cancel">Cancel</a>
    <p>names: <pre data-bind="text: ko.toJSON($root.names)"></pre></p>
</div>

CSS

.edit-form label { color: #888; }
.edit-form a { cursor: pointer; }
.edit-form a:hover { color: #ff0066; }

JavaScript

var seedData = [
	{ id: 1, name: 'Location1', state: 'md', headline: 'headline1', type: { id: 1, name: 'Public' } },
	{ id: 2, name: 'Location2', state: 'va', headline: 'headline2', type: { id: 2, name: 'Private' } },
	{ id: 3, name: 'Location3', state: 'md', headline: 'headline3', type: { id: 1, name: 'Public' } }
];

function Location(data, types, names) {
    var self = this;
        
    self.id = data.id;
    self.name = ko.observable(data.name).extend({ maxLength: 10, unique: { collection: names, externalValue: true } });
    self.state = ko.observable(data.state).extend({ pattern: '^[A-Za-z]{2}$'});
    self.headline = ko.observable();
    self.type = ko.observable();   
    self.errors = ko.validation.group(self);
    
    //update the data at any time
    self.update = function(data) {
        self.name(data.name);
        self.state(data.state);
        self.headline(data.headline);
        
        //set type to the correct reference
        var id = data.type && data.type.id,
            match = id && ko.utils.arrayFirst(types, function(type) {
               return type.id === id; 
            });

        self.type(match);
    };
    
    //initialize with our initial data
    self.update(data);
};

function ViewModel() {
	var self = this;
	
    self.types = [
        { id: 1, name: 'Public' },
        { id: 2, name: 'Private' }
    ];
    
    self.locations = ko.observableArray([]);   
    
	self.selectedLocation = ko.observable();
	self.selectedLocationForEditing = ko.observable();
    
    self.names = ko.computed(function(){
        return ko.utils.arrayMap(self.locations(), function(item) {
            return item.name();
        });
    });  
    
    self.namesExcept = function(name){
        return ko.utils.arrayMap(self.locations(), function(item) {
            if (item.name() !== name)
                return item.name();
        });
    }
     
	self.edit = function(item) {
		self.selectedLocation(item);
       ...