形式不承认传递的财产价值

时间:2017-10-01 07:46:29

标签: angular

在我的component.ts文件中,我将值添加到属性中:

ngOnInit() {

        this.route.params.subscribe(params => {

            this.param = params['id'];
            this.pagesService.getEditPage(this.param).subscribe(page => {
                this.page = page;
            });

        });

    }

但是在模板中,我有一个带有文本输入和textarea的表单,该表单的行为就好像它没有任何值。

这是表格代码:

<form novalidate #f="ngForm" (ngSubmit)="editPage(f)">
    <div class="form-group">
        <label for="">Title:</label>
        <input type="text" class="form-control" placeholder="Title" name="title" value="{{page?.title}}" [(ngModel)]="title" #pageTitle="ngModel"
            minlength="2" required />
    </div>
    <div class="alert alert-danger" *ngIf="pageTitle.errors?.required && pageTitle.touched">
        Title is required.
    </div>
    <div class="alert alert-danger" *ngIf="pageTitle.errors?.minlength && pageTitle.touched">
        Minimum length is 2.
    </div>

    <div class="form-group">
        <label for="">Content:</label>
        <textarea class="form-control" name="content" placeholder="Content" cols="30" rows="10" [(ngModel)]="content" #pageContent="ngModel"
            minlength="5" required>{{ page?.content }}</textarea>
    </div>
    <div class="alert alert-danger" *ngIf="pageContent.errors?.required && pageContent.touched">
        Content is required.
    </div>
    <div class="alert alert-danger" *ngIf="pageContent.errors?.minlength && pageContent.touched">
        Minimum length is 5.
    </div>

    <div class="form-group">
        <button class="btn btn-default" [disabled]="!f.valid">Edit page</button>
    </div>
</form>

当显示表单时,文本输入具有正确的值,但它的行为就好像没有,因为它的验证启动了,而textarea根本没有显示真实内容,它显示了占位符内容(但是当我检查textarea时,我可以看到它的真实内容。)

是因为在获取数据和显示表单之间有一些延迟还是什么?以及如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

您通过同时使用 fabric.Object.prototype.transparentCorners = false; canvas = this.__canvas = new fabric.Canvas('c', { backgroundColor: '#333', HOVER_CURSOR: 'pointer' }); fabric.Polaroidphoto = fabric.util.createClass(fabric.Image, { type: 'polaroidphoto', H_PADDING: 20, V_PADDING: 20, originX: 'center', originY: 'center', initialize: function(src, options) { this.image = new Image(); this.image.src = src; this.callSuper('initialize',src, options); console.log("initialize, src:" + src); this.image.onload = (function() { this.width = this.image.width; console.log("initialize, scaleX:" + this.image.scaleX); this.height = this.image.height; this.src= this.image.src; console.log("initialize image.onload, src:" + src); this.loaded = true; this.setCoords(); this.fire('image:loaded'); }).bind(this); }, _render: function(ctx) { if (this.loaded) { console.log("_render:is_loaded"); ctx.fillStyle = '#fff'; ctx.fillRect( -(this.width / 2) - this.H_PADDING, -(this.height / 2) - this.H_PADDING, this.width + this.H_PADDING * 2, this.height + this.V_PADDING * 2); ctx.drawImage(this.image, -this.width / 2, -this.height / 2); } else { console.log("_render:is_NOT__loaded"); } } }); // Added fromObject function for sub-class fabric.Polaroidphoto.async = true; fabric.Polaroidphoto.fromObject = function (object, callback) { console.log("fabric.Polaroidphoto.fromObject object.src) :" + object.src); var instance = new fabric.Polaroidphoto(object.src, object); callback && callback(instance); // added handler to render instance instance.on('image:loaded', when_loaded ); }; var photo = new fabric.Polaroidphoto('https://i.stack.imgur.com/cqmQ9.png', { }); photo.on('image:loaded', when_loaded ); photo.set('scaleX', 1); photo.set('scaleY', 1); photo.set('top', 180); photo.set('left', 150); canvas.add(photo); canvas.add( rect= new fabric.Rect({ top: 50, left: 100, width: 50, height: 50, fill: '#f55' }), circle = new fabric.Circle({ top: 140, left: 230, radius: 75, fill: 'green' }), triangle = new fabric.Triangle({ top: 300, left: 210, width: 100, height: 100, fill: 'blue' }) ); // required at load to render sub-classed image in group function when_loaded() { console.log("when_loaded"); dirty(); // to set dirty : true canvas.renderAll(); } // required at load to display sub-classed image in group, // set dirty:true for groups function dirty() { $.each(canvas._objects, function( index, obj ) { if( typeof obj.type !== 'undefined' && obj.type == 'group') { obj.dirty= true; } }); } $("#group").on('click', function() { var activegroup = canvas.getActiveGroup(); var objectsInGroup = activegroup.getObjects(); activegroup.clone(function(newgroup) { canvas.discardActiveGroup(); objectsInGroup.forEach(function(object) { canvas.remove(object); }); canvas.add(newgroup); newgroup.dirty = true; }); }); $("#ungroup").click(function(){ var activeObject = canvas.getActiveObject(); if(activeObject.type=="group"){ var items = activeObject._objects; alert(items); activeObject._restoreObjectsState(); canvas.remove(activeObject); for(var i = 0; i < items.length; i++) { canvas.add(items[i]); items[i].dirty = true; canvas.item(canvas.size()-1).hasControls = true; } canvas.renderAll(); } }); ngModel来滥用模板驱动的表单。您还错过了关于Angular的整个想法,您的模型定义了应用程序的状态,模板是一种装饰性地表达如何呈现该模型的方式。

你根本不应该使用value。使用value,您已经正确地在您已经放置此指令的输入控件和您的类中的变量[(ngModel)]="title"之间创建了双向绑定。如果您希望更新输入,则应更改模型,并自动更新视图。因此,在title中,您应该执行以下操作。

.subscribe

Angular会注意到更新this.title = page.title ,因为title,该更改会在视图中显示出来。

与您的问题无关,但您也在滥用RxJS。嵌套订阅是反模式和潜在的内存泄漏。要make dependent requests using RxJS,您可以使用switchMap operator

[ngModel]="title"

如果由于某种原因需要保存this.route.params .map(params => params.id) // or .pluck('id'), but you lose type safety .switchMap(params => this.pageService.getEditPage(params)) .subscribe(page => this.page = page); 的中间结果,可以使用params['id']运算符,或者在从.do内的lambda返回之前保存它。