Нажмите «Привязка из шаблона компонента», чтобы обновить HTML-класс Angular2.

У меня возникают трудности с выяснением того, как передавать обновленные значения из привязки кликов из одного шаблона в другой. По сути, я создаю приложение репозитория компонентов, в котором пользователь сможет просматривать компонент и обновлять параметры для него на странице. Большинство этих опций могут совместно использоваться компонентами, поэтому я создал отдельные файлы для хранения этих часто используемых опций.

В приведенном ниже примере класс по умолчанию col-xs-4 добавляется к компоненту, как и предполагалось, но событие щелчка не обновляет класс, хотя само событие работает, так как регистрируется его обновление. значение столбцов в классе. Кажется, мне нужен какой-то прослушиватель событий для его обновления, но я не уверен, как с этим справиться.


content-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>

content-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, я был бы очень признателен.


person JSess    schedule 16.11.2015    source источник
comment
Вы ищете что-то вроде этого пример?   -  person Eric Martinez    schedule 18.11.2015
comment
Эй, большое спасибо за ваш ответ. Я заметил, что основным отличием здесь является конструктор с внедрением класса для безопасного использования с хоста для создания экземпляра. В любом случае, это сработало в моем локальном приложении, поэтому, если бы вы могли объяснить, что именно он делает вместе в ответе, я обязательно отмечу это.   -  person JSess    schedule 18.11.2015


Ответы (1)


Как вы сказали, пример в моем комментарии не сильно отличается. Я просто использую @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] и зачем они мне нужны?. Ответ довольно прост: дочерний компонент не знает о своем родителе (приложении), поскольку он не существует, когда вызывает его. Поэтому они нужны нам для получения ссылки на класс, который будет существовать. [3]

Но, может быть, вы хотите избежать их использования, как? Измените порядок занятий. Посмотрите этот небольшой пример

(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 в пример как часть ответа: пример plnkr

Надеюсь, я был достаточно ясен :)

Справочник

[1] Документация для @Inject()

[2] Документация для forwardRef

[3] Классы в javascript не поднят

person Eric Martinez    schedule 18.11.2015
comment
Это идеально - очень четко описывает проблему с прямыми ссылками для получения дополнительной информации. 10/10, еще раз отметит ваш ответ. Спасибо! - person JSess; 19.11.2015