单击从组件模板绑定以更新 HTML Class Angular2

Click Binding from Component Template to Update HTML Class Angular2

我很难弄清楚如何将更新后的值从一个模板的点击绑定传递到另一个模板。本质上,我正在创建一个组件存储库应用程序,用户可以在其中查看组件并在页面上更新它的选项。这些选项中的大多数都可以在组件之间共享,因此我创建了单独的文件来存储这些常用选项。

在下面的示例中,默认的 col-xs-4 class 正在按预期添加到组件中,但点击事件不会更新 class,即使事件本身有效,但在记录时它会更新 class 中的列值。看来我需要某种事件侦听器才能更新,但我不确定如何处理。


内容-tout.html

<div class="row">
    <div [ng-class]="columnAmount" class="content-tout">
        Tout
    </div>
</div>

<hr />

<h2>Options</h2>
<p>Use the following buttons to update the values in the component above.</p>
<options></options>

内容-tout.ts

import { Component, View, NgClass } from 'angular2/angular2';

// this is option for changing column class from the ng-class in the template
import { ColumnsOption } from '../../shared/options/columns';


@Component ({
    selector: 'contentPlaceholder',
    bindings: [ColumnsOption]
})

@View ({
    templateUrl: '/app/components/content-tout/content-tout.html',
    directives: [ColumnsOption, NgClass]
})


export class ContentTout {
    private columnAmount: string;

    constructor(private columnsOption:ColumnsOption) {
        this.columnAmount = this.columnsOption.columns;
    }
}

columns.ts

import { Component, View, NgFor } from 'angular2/angular2';

@Component ({
    selector: 'options'
})

@View ({
    template: `
        <hr />
        <h3>Columns / Width</h3>
        <nav>
            <button *ng-for="#column of columnsCollection" (click)="changeColumns(column)" class="btn btn-primary-outline" type="button">
                {{ column }}
            </button>
        </nav>
    `,
    directives: [ NgFor ]
})


export class ColumnsOption {

    private columnsCollection: Array<string> = [
        'col-xs-1', 'col-xs-2', 'col-xs-3', 'col-xs-4', 'col-xs-5', 'col-xs-6', 'col-xs-7', 'col-xs-8', 'col-xs-9', 'col-xs-10', 'col-xs-11', 'col-xs-12'
    ];
    public columns: string = "col-xs-4";


    private changeColumns(column: string) {
        this.columns = column;
    }
}

我在 Angular2 中使用点击绑定做了很多搜索,只遇到示例与绑定位于同一视图中的资源。我希望这种模块化方法是可能的,所以如果有人有任何资源供我阅读,或者 API 预览中的特定显示,我将非常感激。

就像你说的,我评论中的例子并没有什么不同。我只是使用 @Host() 来获取对子组件中父组件的引用。

这是父类,我们只添加一个方法来修改它自己的方法 column 属性 将被子类的同名方法调用(为了方便,您可以调用随心所欲)

@Component({
  template : `
     <div [class]="columns">{{columns}}</div>
     <columns></columns>
  `,
  directives : [Columns]
})
export class App {
  columns = "col-xs-4";
  changeColumn(column) {
    this.columns = column;
  }
}

然后在子组件中唯一的区别,就像你说的是这个代码片段

constructor(@Host() @Inject(forwardRef(() => App)) app: App) {
    this.app = app;
}

changeColumns(column) {
    this.app.changeColumn(column);
}

在构造函数中我保存对父组件的引用然后在子方法中changeColumns我调用父方法changeColumns.

现在,您可能在问 Inject [1] 和 forwardRef [2] 到底是什么,我为什么需要它们? .答案很简单:子组件不知道其父组件 (App),因为在调用它时它不存在。所以我们需要他们获得对 存在的 class 的引用。 [3]

但也许您想避免使用它们,如何避免?更改 classes 的顺序。看这个小例子

(Child calls Parent but it doesn't exist yet = Fail)
class Child  {}
class Parent {}

// So move parent to be above of its Child
class Parent {}
class Child {}

在后一种情况下,您可以通过如下简单地调用父级来节省几次击键

constructor(@Host() app: App) {
    this.app = app;
}

将示例中的 plnkr 添加为答案的一部分:example plnkr

希望我说得足够清楚:)

参考

[1] Documentation for @Inject()

[2]Documentation for forwardRef

[3]Classes in javascript aren't hoisted