2016-01-18 2 views
4

У меня есть Угловое 1 приложение, которое работает с простой contentEditable директивы, которые могут быть использованы, как это в шаблонах:Изменение свойства компонента из директивы в Angular2

<span contenteditable="true" ng-model="model.property" placeholder="Something"> 

Редактирование элемента уволит $setViewValue(element.html() и работал ожидается.

Я хотел бы сделать что-то в Angular2 с аналогичным сжатым синтаксисом шаблонов. В идеале я хотел бы шаблон, чтобы выглядеть следующим образом:

<span contentEditable="true" [(myProperty)]="name"></span> 

где «имя» является свойство на компоненте и есть директива обновить компонент при изменении. Я чувствую, что я близко с этим (Plunker Link):

//our root app component 
import {Component, Input, Output Directive, ElementRef, Renderer, OnInit} from 'angular2/core' 

@Directive({ 
    selector: '[contentEditable]', 
    host: { 
     '(blur)': 'update($event)' 
    } 
}) 

export class contentEditableDirective implements OnInit { 
    @Input() myProperty; 
    constructor(private el: ElementRef, private renderer: Renderer){} 

    update(event){ 
     this.myProperty = this.el.nativeElement.innerText; 
    } 
    ngOnInit(){ 
     this.el.nativeElement.innerText = this.myProperty; 
    } 
} 

Эта идея работает, если я передать объект как {name: "someName"}, но если просто передать свойство похоже, это передавая значение, но не ссылки и т.д. привязка не возвращается к компоненту. Есть ли способ сделать это, который по-прежнему позволит синтаксис шаблона, который не является подробным, но все же позволяет легко повторно использовать директиву.

+0

Я добавлю, что могу сделать это, если я добавлю 2 ввода в директиву и передаю как имя объекта, так и имя свойства как отдельные входы.Мой шаблон будет выглядеть следующим образом: '' Тогда я могу манипулировать 'myobject [property]' из директивы. Однако предпочел бы более чистый способ. –

ответ

4

Директива не знает о ее материнской компании name. Вы можете хотя и выпустить событие из директивы и уловить его в родительском. Проверьте этот пример

@Directive({ 
    selector: '[contentEditable]', 
    host: { 
     '(input)': 'update($event)' // I changed it to input to see the changes immediatly 
    } 
}) 
export class contentEditableDirective implements OnInit { 

// Output that will emit outside the directive 
@Output() updateProperty: EventEmitter<any> = new EventEmitter(); 

// When 'update' is called we emit the value 
update(event){ 
    this.updateProperty.emit(this.el.nativeElement.innerText); 
} 

Теперь, когда наша директива излучает правильно, мы должны поймать значение в компоненте. Для краткости только шаблон

<div contentEditable="true" [myProperty]="name" (updateProperty)="name = $event"></div> 

updateProperty является @Output из директивы. Когда он запускается, мы его поймаем, и значение, которое мы выбрали, будет присвоено $event. После этого мы назначим $event нашей собственности name, и вы получили свое приложение.

Ваша деятельность составляет plnkr. Я надеюсь, что это помогает.

Update

Благодаря этому answer я увидел, что это возможно, что вы просили.

Вы можете сопоставить Output с тем, что вызывается, когда синтаксис [()] снят. Если у вас есть синтаксис, как [(myProperty)]="expr" он обессахаренная к [myProperty]="expr" (myPropertyChange)="expr = $event"

Так изменяя первоначальный ответ следующим образом

@Output() myPropertyChange: EventEmitter<any> = new EventEmitter(); 
update(event){ 
    this.myPropertyChange.emit(this.el.nativeElement.innerText); 
} 

Это даст вам этот шаблон, который является то, что вы просили с самого начала.

<div contentEditable="true" [(myProperty)]="name"></div> 

Вот plnkr обновлен на правильный правильный ответ.

+0

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

+0

@MarkM Я обновил свой ответ, чтобы отразить то, что вы действительно просили. Мне очень жаль, если я буду вводить вас в заблуждение. –

+0

Да! Это гораздо более приятное решение. Спасибо за обновление - я не думаю, что когда-нибудь это сообразил. –