从Angular2中的指令更改零部件属性 [英] Changing Component Property from Directive in Angular2

查看:101
本文介绍了从Angular2中的指令更改零部件属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Angular 1应用程序,该应用程序可以使用简单的contentEditable指令,可以在模板中像这样使用该指令:

I have an Angular 1 app that works with a simple contentEditable directive, which can be used like this in templates:

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

编辑该元素会触发$setViewValue(element.html(),并且按预期方式工作.

Editing the element would fire $setViewValue(element.html() and it worked as expected.

我想用类似的简洁模板语法在Angular2中做点什么.理想情况下,我希望模板看起来像这样:

I would like to make something in Angular2 with a similarly succinct template syntax. Ideally, I would like the template to look like this:

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

其中,名称"是组件上的属性,并具有指令,用于在更改组件时更新组件.我觉得我对此很满意(柱塞链接):

where 'name' is a property on the component and have the directive update the component when changed. I feel like I'm close with this (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"}这样的对象,这个想法就行了,但是如果只是传递一个属性,则好像它传递的是值,而不是引用,因此绑定不会流回组件.有没有一种方法可以做到这一点,它仍然允许模板语法不冗长,但仍然可以轻松地重用指令.

This idea works if I pass an object like {name: "someName"} but if just pass a property it seems like it's passing the value, but not the reference and so the binding doesn't flow back to the component. Is there a way to do this that will still allow a template syntax that isn't verbose but still allows easy reuse of the directive.

推荐答案

该指令不知道其父name属性.不过,您可以从指令发出事件,并将其捕获到父对象中.检查这个例子

The directive doesn't know about its parent name property. You can though emit an event from the directive and catch it in the parent. Check this example

@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);
}

现在我们的指令正确发出了,我们必须在组件中捕获值. 为简洁起见,仅模板

Now that our directive is emitting correctly, we have to catch the value in the component. For brevity only the template

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

updateProperty是指令中的@Output.当它被触发时,我们将其捕获,并将我们所分配的值分配给$event.之后,我们将$event分配给属性name,您的应用即可正常工作.

updateProperty is the @Output from the directive. When it gets triggered we catch it and the value we emied will be assigned to $event. After that we assign $event to our property name and you got your app working.

这是您 plnkr 的工作.希望对您有帮助.

Here's your plnkr working. I hope it helps.

感谢此 answer 我看到可能是您要的.

Thank to this answer I saw that it is possible what you asked for.

您可以将输出与语法[()]终止时所调用的内容匹配.如果您使用[(myProperty)]="expr"这样的语法,则将其替换为[myProperty]="expr" (myPropertyChange)="expr = $event"

You can match the Output to what is called when the syntax [()] is desugared. If you have a syntax like [(myProperty)]="expr" it is desugared to [myProperty]="expr" (myPropertyChange)="expr = $event"

因此将原始答案更改为以下内容

So changing the original answer to as follows

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

它将为您提供此模板,这是您从一开始就要求的.

It will give you this template, which is what you asked from the beginning.

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

这是 plnkr 已更新为真正的正确答案.

Here's the plnkr updated to the real correct answer.

这篇关于从Angular2中的指令更改零部件属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆