How ng-message is connected to model, and how can I show the message using ng-message?

Your main ng-messages argument is tied to myForm.field1.$error, but you never actually add an error to the form.field1.$error. So in your controller, just manually add an error to the $error object via $setValidity(field, isValid):

if ($scope.data.field1 != 'aaa') {
    form.field1.$setValidity('validationError', false);
    // Angular will make form.field1.$error.validationError = true;
}
else {
    form.field1.$setValidity('validationError', true);
    // Angular will make form.field1.$error.validationError = false;
}

Then, you can just have the ng-message directive do its work. The child elements that provide ng-message are evaluated as properties of their parent ng-messages already (note the extra s). So typically, this is used with the parent being the form element's $error object and the inner children are the properties like $error.required or in your case $error.validationError. No need for ng-message-exp here:

<div ng-messages="myForm.field1.$error" style="color:red">
    <div ng-message="validationError">this is the error</div>
</div>

Fixed plunker


The more proper way to do this in controller is to use $setValidity

if(a !== b){
    form.inputName.$setValidity('custom-err', false);
} else {
    form.inputName.$setValidity('custom-err', true);
}

form.$setSubmitted();

The Dmitry K's answer it's excellent.

I´m going to expand the answer.

//Function before show your form:
vm.showForm(form){
        form.$setPristine();
        form.$setUntouched();
        form.myFieldName.$setValidity('myCustomValidationName', false);

        //More code...
}

//funtion to validate field on "ng-change"
vm.validateField(form){

    if(xxxx == yyy) //Make your own validation{
       form.myFieldName.$setValidity('myCustomValidationName', true);
    }else{
       form.myFieldName.$setValidity('myCustomValidationName', false);
    }

}

And the relevant HTML code:

<form name="myFormName" novalidate>
    <md-input-container class="md-block">
        <label>myField</label>
        <input ng-model="ctrl.myFieldName" name="myFieldName" ng-change="ctrl.validateField(myFormName)" />

        <div ng-show="myFormName.myFieldName.$touched || myFormName.$submitted">
            <div ng-messages="myFormName.myFieldName.$error">
                <div ng-message="myCustomValidationName">this is the message to show</div>
            </div>
        </div>
    </md-input-container>
</form>

Tags:

Angularjs