Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom ValidationController #469

Closed
d-kostov-dev opened this issue Sep 28, 2017 · 7 comments · Fixed by aurelia/hot-module-reload#19
Closed

Custom ValidationController #469

d-kostov-dev opened this issue Sep 28, 2017 · 7 comments · Fixed by aurelia/hot-module-reload#19

Comments

@d-kostov-dev
Copy link

d-kostov-dev commented Sep 28, 2017

I am trying to extend the ValidationController.

I started with this:

import { inject } from 'aurelia-framework';
import { ValidationController, Validator, PropertyAccessorParser } from 'aurelia-validation';

@inject(Validator, PropertyAccessorParser)
export class CustomValidationController extends ValidationController {
  constructor(private injectedValidator: Validator, private injectedPropertyParser: PropertyAccessorParser) {
    super(injectedValidator, injectedPropertyParser);
  }
}

It works fine.

But when I add the '& validate' biding behavior in my form I get:
"Error: A ValidationController has not been registered."

The "problem" is that the base binding behavior (validate-binding-behavior-base.ts) is using this line to get the controller:
"controller = source.container.get(Optional.of(ValidationController));"
and it does not exist in my class (it's CustomValidationController).

Any ideas how to work around this? Will any future releases allow such functionality?

Thanks.

@d-kostov-dev
Copy link
Author

d-kostov-dev commented Oct 1, 2017

Ok. Small update. It is supported by using "& validate:validationController".

So it's actually supported functionality, but we always have to type the validation controller. It will be nice if we can do it once in configuration for example. :)

Thanks

@jdanyow
Copy link
Contributor

jdanyow commented Oct 5, 2017

If you create a gist that shows what you're doing I'll be able to help.

https://gist.run/?id=381fdb1a4b0865a4c25026187db865ce

@d-kostov-dev
Copy link
Author

d-kostov-dev commented Oct 5, 2017

Here is a working example: https://gist.run/?id=9f117dd3f760035c67a64e90c2f62d33
Here is the error I get if i don't use "& validate:validationController" on the input fields: https://gist.run/?id=4eaf26e2cc48c48cbcd95399fb787631

P.S. I just add a property to the validation controller to show me if there is ANY errors. Just a boolean. This way I can disable the submit button on initial load. But that's not the issue. The issue is that using a custom validation controller is possible...but I have to type it in every input. The idea was to make it possible by configuration to be typed once. :)

@jdanyow
Copy link
Contributor

jdanyow commented Oct 6, 2017

use @inject(NewInstance.of(CustomValidationController).as(ValidationController)) (make sure you've imported ValidationController)

@jdanyow jdanyow closed this as completed Oct 6, 2017
@alexdresko
Copy link

I think I've run into the same problem... or at least something similar. I've reproduced the problem easily.

Given this template..

<template>
    <input type="text" placeholder="Enter name" value.bind="name & validate"> asdfasdfasdfasdfasdf
</template> 

...and this view model...

import { autoinject } from 'aurelia-framework';
import { ValidationControllerFactory, ValidationController } from 'aurelia-validation';

@autoinject
export class CreateEditForm{
    constructor(private readonly validationControllerFactory: ValidationControllerFactory) {
        this.validation = this.validationControllerFactory.createForCurrentScope();
    }

    name: string;
    
    validation: ValidationController;
}

... we see the following exception in the browser console window any time we edit the template:

Uncaught (in promise) Error: A ValidationController has not been registered.
at ValidateBindingBehavior.56.ValidateBindingBehaviorBase.bind (validate-binding-behavior-base.js:26)
at BindingBehavior.bind (aurelia-binding.js:1189)
at Binding.bind (aurelia-binding.js:4822)
at View.bind (aurelia-templating.js:1396)
at rerenderController (render-utils.js:50)
at aurelia-hot-module-reload.js:215
at Set.forEach ()
at HmrContext. (aurelia-hot-module-reload.js:215)
at step (aurelia-hot-module-reload.js:31)
at Object.next (aurelia-hot-module-reload.js:12)

In other words, as soon as we save the file, HMR tries to reload the template and that exception occurs. Of course, I can refresh the page to fix the problem, but that negates the usefulness of HMR.

Now, if I remove & validate from the template, the error goes away. HMR refreshes the page properly (but the element is no longer validated).

Hopefully these details will help diagnose the problem. We would love to be able to use HMR and the validate plugin at the same time.

@alexdresko
Copy link

Hrmmm.. Looking elsewhere, I discovered that changing & validate to & validate:validation in the template above fixes the problem. Can someone explain why that change has to be made? Is that the correct fix?

@ErikSchierboom
Copy link
Contributor

ErikSchierboom commented Nov 21, 2017

I have the exact same issues as @alexdresko, also using Webpack with HMR. And the proposed workaround (passing the validation controller to validate) also fixes the issue for me.

rluba added a commit to rluba/hot-module-reload that referenced this issue Jun 27, 2018
`recreateView` creates a new container but did not copy the resolvers from the old container. This caused local DI instances (eg. injected into the controller via `NewInstance.of`) to be missing.

This fixes aurelia/validation#469, at least the HMR issue described by @alexdresko.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants