【问题标题】:angular 2 equivalent of vuejs v-bindAngular 2 相当于 vuejs v-bind
【发布时间】:2019-06-03 14:34:56
【问题描述】:

正如标题所暗示的,我正在寻找一种方法来将具有多个属性的对象绑定到组件@Inputs,而不必显式编写所有属性

假设我有这个对象

let params = {
    delta: 0.2,
    theta: 2.3,
    sigma: 'foo',
}

不必像这样单独绑定所有这些

<my-component
    [delta]="params.delta"
    [theta]="params.theta"
    [sigma]="params.sigma"/>

我想一次性绑定所有这些。

<my-component [someDirectiveIDontKnow]="params"/>

我该怎么做?

找到了一个指向先前询问的question 的链接,但无法使其正常工作。

编辑: 我不是在问如何绑定@Inputs。想象一下,我正在渲染的组件有 40 个 @Inputs,并且我不允许重写它以只接受一个 @Input 可以包含所有参数。

所以编写一个使用这个组件的模板变得非常丑陋和庞大。

....
<my-component
  [param1]="params.param1"
  [param2]="params.param2"
  [param3]="params.param3"
  [param4]="params.param4"
  [param5]="params.param5"
  [param6]="params.param6"
  [param7]="params.param7"
  [param8]="params.param8"
  [param9]="params.param9"
  [param10]="params.param10"
  [param11]="params.param11"
  [param12]="params.param12"
  [param13]="params.param13"
  [param14]="params.param14"
  ... and so on ....
/>
....

【问题讨论】:

  • 您的组件&lt;my-component&gt; 应该在其component.ts 中有@Input params。然后你用括号绑定&lt;my-component [params]="myParamObject"&gt;
  • 我不知道这是否可能,但我当然不喜欢它。我怀疑这是不可能的,因为 Angular 会验证输入属性 - 即,如果您为没有 thing 输入属性的组件添加 [thing]="true",Angular 会引发错误。
  • @Vlad274 它只是将一个对象作为输入传递。当然有可能。至于OP,RTFM !
  • 对于那些没有抓住重点的人:问题不是“我可以传递一个对象吗?”问题是“我可以让一个对象扩展/展平它的属性吗?”

标签: javascript angular vuejs2


【解决方案1】:

在我看来,最好将它们全部定义在一个模型中

您将从以下模型开始

params.model.ts

import {SomeOtherModel} from './some-other.model'

export interface ParamsModel {
    paramName1: string;
    paramName2?: string;
    paramName3?: number;
    paramName4: SomeOtherModel;
}

然后在您的组件中,您可以强制您的输入采用特定的模型参数

my.component.ts

import {ParamsModel} from './params.model';

@Component({..})
class MyComponent {
  @Input() params: ParamsModel;
}

app.component.html

<my-component params="paramsModel"></my-component>

app.component.ts

import {ParamsModel} from './params.model';

@Component({..})
class AppComponent implements OnInit {
    paramsModel: ParamsModel;


    ngOnInit(): void {
        this.paramsModel = <ParamsModel>{someValue: someValue};
    }
}

这样你就有了完整的代码完成。

请注意! Angular 不会对内容进行深度观察,因此更改 Params 对象内部的内容,在 javascript 中仍然具有相同的对象 ID,导致 Angular 看不到更改。

有一些解决方法

1:绑定每个参数(这正是你不想要的)

2:当改变模型的内容时,每次销毁实例并创建一个新的实例,你可以通过在模型中添加一个构造函数并像这段代码一样转换它来做到这一点

export class ParamsModel {
    paramName1: string;
    paramName2?: string;
    paramName3?: number;
    paramName4: SomeOtherModel;

    constructor(config?: ParamsModel) {
        Object.assign(this, config);
    }
}

// first init
this.paramsModel = new ParamsModel(<ParamsModel>{someValue: someValue});

// updated init
this.paramsModel = new ParamsModel(this.paramsModel);
this.paramsModel.changedValue = changedValue; // (could also use an extend function on original params model)

3:创建带有事件的观察者,并在另一端触发更新事件

4:使用 ngDoCheck 自行检查内容是否发生变化

【讨论】:

  • 优秀的答案!这个答案的后半部分非常重要,每个人都应该读两遍。一个小问题:“你可以强制你的输入采用特定的模型参数”——技术上不正确,这只是 Typescript 的语法糖,在运行时它可以是任何东西而不会引发特定错误(尽管使用它的逻辑可能会中断)。这给我带来了令人讨厌的痛苦,所以我提到它是为了提醒其他人
【解决方案2】:

在 Angular 中没有通用指令来传递输入属性。但是,Angular 支持绑定任何有效的 JavaScript 类型,无论是对象、数组还是原语。

在模板中

<my-component [params]="params"/>

在类中,您必须使用@Input 装饰器将对象标记为输入。您可以在任何生命周期挂钩中访问它的值,如下所示。请注意,params 不会在构造函数中设置,因为视图绑定是在类实例化后执行的。

class MyComponent {
  @Input()
  params: any

  constructor() { }   // <-- params not set

  ngOnChanges() { } // <-- anytime params changes

  ngOnInit() { } // <-- once when the component is mounted

}

【讨论】:

    猜你喜欢
    • 2015-11-27
    • 2017-08-31
    • 1970-01-01
    • 2018-01-24
    • 2016-12-14
    • 1970-01-01
    • 2017-02-08
    • 2017-04-01
    • 1970-01-01
    相关资源
    最近更新 更多