As validações estão sendo feita com a propriedade submitted do formulário (formulario.$submitted).
<div class="page-header text-center">
<h1>{{foto.titulo}}</h1>
</div>
<p ng-show="mensagem.length" class="alert alert-info">{{mensagem}}</p>
<form novalidate name="formulario" class="row" ng-submit="submeter()">
<div class="col-md-6">
<div class="form-group">
<label>Título</label>
<input name="titulo" class="form-control" ng-model="foto.titulo" required ng-maxlength="20">
<span ng-show = "formulario.$submitted && formulario.titulo.$error.required" class="form-control alert-danger">
Título obrigatório
</span>
<span ng-show = "formulario.$submitted && formulario.titulo.$error.maxlength" class="form-control alert-danger">
No máximo 20 caracteres!
</span>
</div>
<div class="form-group">
<label>URL</label>
<input name="url" class="form-control" ng-model="foto.url" required>
<span ng-show = "formulario.$submitted && formulario.url.$error.required" class="form-control alert-danger">
URL obrigatória
</span>
</div>
<div class="form-group">
<label>Descrição</label>
<textarea name="descricao" class="form-control" ng-model="foto.descricao">
</textarea>
</div>
<button type="submit" class="btn btn-primary" ng-disabled="formulario.$invalid">
Salvar
</button>
<a href="/" class="btn btn-primary">Voltar</a>
<hr>
</div> <!-- fim div col-md-6 -> primeira coluna-->
<div class="col-md-6">
<minha-foto url="{{foto.url}}" titulo="{{foto.titulo}}"></minha-foto>
</div>
</form>
Alterei a propriedade formulario.$submitted para false no foto-controller e funcionou.
angular.module('alurapic').controller('FotoController', function($scope, $http) {
$scope.foto = {};
$scope.mensagem = '';
$scope.submeter = function() {
if ($scope.formulario.$valid) {
$scope.formulario.$submitted = false;
$http.post('/v1/fotos', $scope.foto)
.success(function() {
$scope.foto = {};
$scope.mensagem = 'Foto cadastrada com sucesso';
})
.error(function(erro) {
console.log(erro);
$scope.mensagem = 'Não foi possível cadastrar a foto';
})
}
};
});
Obrigado!