2015-11-16 2 views
0

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

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


контента 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, я бы очень его оценил.

+1

Вы ищете что-то вроде этого [например] (http://plnkr.co/edit/ wqFzxGDn9pzURjAFDxXu? р = предпросмотр)? –

+0

Эй, большое спасибо за ваш ответ. Я заметил, что основное отличие здесь - конструктор с введением класса для безопасного использования с хоста для создания экземпляра. В любом случае, это сработало в моем локальном приложении, поэтому, если бы вы могли объяснить, что именно он делает вместе в ответ, я обязательно отмечу его. – JSess

ответ

2

Как вы сказали, пример в моем комментарии не так уж и отличается. Я просто использую @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 в примере, чтобы быть частью ответа: example plnkr

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

Ссылка

[1] Documentation for @Inject()

[2] Documentation for forwardRef

[3] Classes in javascript aren't hoisted

+0

Это прекрасно - описание проблемы очень понятно с помощью прямых ссылок для получения дополнительной информации. 10/10, повторит ваш ответ. Благодаря! – JSess