【问题标题】:Angular 2 two way data binding with ngModelAngular 2 与 ngModel 的双向数据绑定
【发布时间】:2016-10-12 10:17:48
【问题描述】:

首先我是 Typescript 和 Angular 2 的新手,这似乎是一个显而易见的答案,但我似乎无法让它工作。我有以下型号

export interface IBrand {
    brandID: number;
    name: string;
    image: string;
}

那么我就有了组件类

import { Component, OnInit }  from '@angular/core';
import { Router, RouteParams } from '@angular/router-deprecated'
import { bootstrap } from '@angular/platform-browser-dynamic';

import { IBrand } from './brand';
import { BrandService } from './brand.service';

@Component({
    selector: 'data-bind',
    templateUrl: 'app/dashboardApp/brands/brand-list.component.html',
    styleUrls: ['app/dashboardApp/brands/brand-list.component.css']
})

export class BrandListComponent implements OnInit {
    brands: IBrand[];
    errorMessage: string;
    newBrand: IBrand;
    pageTitle: string = 'Brands';

    constructor(private _brandService: BrandService,
        private _router: Router) {
    }

    ngOnInit(): void {
        this._brandService.getBrands()
            .subscribe(
            brands => this.brands = brands,
            error => this.errorMessage = <any>error);
    }    
}

然后我有以下html

<div class="form-group">
    <label for="brandName">Brand:</label>
    <input type="text" class="form-control" placeholder="Name" id="brandName" [(ngModel)]="newBrand.name" />
</div>

我无法让 IBrand 的属性成功运行并出现错误

platform-b​​rowser.umd.js:962 ORIGINAL EXCEPTION: TypeError: Cannot read property 'name' of undefined

但是我可以轻松地将它绑定到 pageTitle 之类的东西。有什么想法可以为我指明正确的方向吗?

【问题讨论】:

    标签: angular


    【解决方案1】:

    我认为您需要初始化您的newBrand 属性,如下所述:

    export class BrandListComponent implements OnInit {
      brands: IBrand[];
      errorMessage: string;
      newBrand: IBrand = {}; // <-----
      pageTitle: string = 'Brands';
    
      (...)
    }
    

    在您的情况下,此属性从未初始化并且您遇到错误:

    无法读取未定义的属性“名称”

    【讨论】:

    • 谢谢!我现在收到一个打字稿错误,说“类型'{}'不可分配给类型'Ibrand'。类型'{}'中缺少属性'brandID'。这是我可以忽略的东西还是我需要实例化属性?
    【解决方案2】:

    您必须为类型编写一个类。不是接口。

    newBrand: Brand = new Brand();
    

    【讨论】:

      【解决方案3】:

      我已经有一段时间没有提出这个问题了,它开始得到一些意见,所以我将添加我的答案。

      首先我需要将我的接口更改为一个类并添加一个构造函数。

      export class Brand {
        constructor() {}
        brandID: number;
        name: string;
        image: string;
      }
      

      现在我有了一个构造函数,我可以使用 new 运算符来实例化对象。

      export class BrandListComponent implements OnInit {
        brands: Brand[];
        errorMessage: string;
        newBrand: Brand = new Brand();
        pageTitle: string = 'Brands';
      
        (...)
      }
      

      现在我在没有任何数据的情况下初始化了所需的品牌,我可以将它绑定到模型。希望这会有所帮助。

      【讨论】:

      • 非常感谢,我不知道为什么,但是当我按照角度文档angular.io/guide/forms#create-the-hero-model-class 它定义了构造函数中的字段时,我收到了cannot read property of undefined.. 的错误,但是当我按照您的回答时(在构造函数之外移动字段)我没有得到任何错误
      • 那是因为他们试图创建一个有值的类。在很多 CRUD 情况下,您希望能够创建没有值的类的实例。如果你加了?在允许它们为空的每个属性名称之后,或者您可以传入一个值。然后角度文档版本将起作用。只是取决于你的需要。
      【解决方案4】:

      如果你不想使用类,你可以遵循这种方法。

      export interface IBrand {
      brandID: number;
      name: string;
      image: string;
      }
      

      现在您可以为这样的类型变量创建空对象。

      brand: IBrand = {} as IBrand;
      

      如果您只想将类用于类型安全,请避免使用类,而是使用接口作为最佳实践来减小包大小。

      【讨论】:

        【解决方案5】:

        您可能已经发现,但您可以/应该使用: newBrand: IBrand = {}; 如果您的接口属性是可选的:

        export interface IBrand {
            brandID?: number;
            name?: string;
            image?: string;
        }
        

        【讨论】:

          猜你喜欢
          • 2017-04-29
          • 2020-09-12
          • 2016-12-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-20
          • 2017-11-02
          • 1970-01-01
          相关资源
          最近更新 更多