Aurelia验证抽象为模型

Aurelia Validation abstracted to Model

本文关键字:模型 抽象 验证 Aurelia      更新时间:2023-09-26

我学习了Scott Allen的Aurelia Pluralsight课程,该课程使用了Aurelia验证插件。

这导致了一个视图模型edit.js:

import {inject} from "aurelia-framework";
import {MovieService} from "./movieService";
import {Router} from "aurelia-router";
import {Validation} from "aurelia-validation";
@inject(MovieService, Router, Validation)
export class Edit {
    constructor(movieService, router, validation) {
        this.service = movieService;
        this.router = router;
        this.validation = validation.on(this)
        .ensure("movie.title").isNotEmpty().hasLengthBetween(3, 50)
        .ensure("movie.releaseYear").isNotEmpty().isNumber().isBetween(1900, 2100)
        .ensure("movie.starRating").isNotEmpty().isNumber().isBetween(0, 5);
    }
    activate(params) {
        this.service.getById(params.id)
            .then(movie => {
                this.movie = movie;
           });
    }
    save() {
        this.validation.validate()
            .then(() => {
                this.service.save(this.movie)
                    .then(movie => {
                        let url = this.router.generate("home");
                        this.router.navigate(url);
                    });
            })
            .catch(() => {
            });
    }
}

和一个视图编辑.html

                <form class="form-horizontal"
                      validate.bind="validation"
                      submit.trigger="save()">
                    <div class="form-group">
                        <label class="col-sm-2" for="title">Title</label>
                        <div class="col-sm-10">
                            <input type="text" id="title" placeholder="Title" value.bind="movie.title" class="form-control"/>
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="col-sm-2" for="rating">Rating</label>
                        <div class="col-sm-10">
                            <input type="text" id="rating" placeholder="Rating" value.bind="movie.starRating" class="form-control" />
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="col-sm-2" for="releaseYear">Release Year</label>
                        <div class="col-sm-10">
                            <input type="text" id="releaseYear" placeholder="Release Year" value.bind="movie.releaseYear" class="form-control" />
                        </div>
                    </div>
                    <div class="pull-right">
                        <a route-href="route:home" class="btn btn-default" role="button">Cancel</a>
                        <input type="submit" class="btn btn-primary" value="Save" />
                    </div>
                </form>

这与防止提交无效数据的验证一样有效。

接下来我想做的是将验证规则从视图模型中抽象出来,并放入模型类中。我创建了一个模型movieModel.js

import {inject} from "aurelia-framework";
import {Validation} from 'aurelia-validation';
import {ensure} from 'aurelia-validation';
@inject(Validation)
export class MovieModel {
    @ensure(function(it){ it.isNotEmpty().hasLengthBetween(3, 50) })
    title = "";
    @ensure(function(it){ it.isNotEmpty().isNumber().isBetween(1900, 2100) })
    releaseYear = "";
    @ensure(function(it){ it.isNotEmpty().isNumber().isBetween(0, 5) })
    starRating = "";
    constructor(validation) {
        this.title = "";
        this.releaseYear = "";
        this.starRating = "";
    }
}

并在视图模型中使用了它,如下所示:

import {inject} from "aurelia-framework";
import {MovieService} from "./movieService";
import {Router} from "aurelia-router";
import {Validation} from "aurelia-validation";
import {MovieModel} from "./movieModel";
@inject(MovieService, Router, Validation, MovieModel)
export class Edit {
    constructor(movieService, router, validation, movieModel) {
        this.service = movieService;
        this.router = router;
        this.movie = movieModel;
        this.validation = validation.on(this.movie);
    }
    activate(params) {
        this.service.getById(params.id)
            .then(movie => {
                this.movie = movie;
           });
    }
    save() {
        this.validation.validate()
            .then(() => {
                this.service.save(this.movie)
                    .then(movie => {
                        let url = this.router.generate("home");
                        this.router.navigate(url);
                    });
            })
            .catch(() => {
            });
    }
}

对视图edit.html的更改只是将validate属性添加到输入字段中,例如

<input type="text" id="title" placeholder="Title" value.bind="movie.title" class="form-control"/>

成为

<input type="text" id="title" placeholder="Title" value.bind="movie.title" validate="title" class="form-control"/>

然而,当我编辑通过activate()函数从服务检索到的电影,然后尝试保存它时,验证会将所有属性标记为"必需"。

我假设视图模型的构造函数中的this.validation=validation.on(this.movie)语句将验证绑定到模型的未填充实例,但我不知道如何克服这一点。

每次更改模型时,都需要创建验证

activate(params) {
    this.service.getById(params.id)
        .then(movie => {
            this.movie = movie;
            this.validation = this.Validation.on(this.movie);
       });
}

UPDATE:在构造函数中

this.Validation = validation;