来自@Output的数据更新为HTML中的绑定,但不包含在表达式逻辑或console.log()

时间:2017-02-18 21:29:22

标签: angular typescript

我尝试使用通过@Output收到的数据来触发我的组件中的if语句。出于测试目的,我在模板

中有这个
{{selectedAnswer | json}}

当我在子组件中选择答案时,此绑定在父组件中起作用,表明数据已到达变量selectedAnswer。然而,当我console.log(this.selectedAnswer)没有记录时。

我也一直试图让它更新为变量来运行if条件。当页面首次加载时,它会在我没有默认选择时选取第一个单选按钮的值。当我点击它们时,测试绑定中的值会更新,但console.logs中没有任何更改。

这是父组件中正在进行的操作。

//data coming in from @Output in child component
public selectedI(selected){ this.selectedAnswer = selected };

//the variable I'm passing it into for use.
selectedAnswer: any;

ngOnChanges() {

    //my way so far of attempting to get the value I want when a selection is made.
    var trigger = this.selectedAnswer? this.selectedAnswer.value1: '';



    console.log(this.selectedAnswer);
}

模板

<multiple-choice-radio *ngIf="expbTrigger"
    [question]  = "question01"
    (selectedO) = "selectedI($event)"
></multiple-choice-radio>

在此处调用它与在绑定中调用它的唯一不同之处是绑定添加了|json管道。我想在表达式中以某种方式做同样的事情吗?在子组件中收集数据的方式就像这样

@Output() selectedO: EventEmitter<any> = new EventEmitter();

//variable for storing values from (click) event
selected = {value1: '', value2: ''};

//(click) event that gets values from template and passes them into "selected"
getSelected(ans) {
    this.selected = { value1: ans.id, value2: ans.answer };
}

//(click) event that sends @Output data to parent component.
public sendAnswer = (): void => {
     this.selectedO.emit(this.selected);
 }

模板

<input type="radio"
    [attr.name]  = "quesForm.value.name"
    [attr.id]    = "ans.id"
    [attr.value] = "ans.answer"
    (click)      = "getSelected(ans)"
    (click)      = "sendAnswer()"
    hidden
/>

我个人感觉我做这一切的方式有点笨重,所以如果你知道一个更干净的方法,请分享。除此之外,我怎样才能让它登录控制台,以及在更新时触发逻辑时可以进一步使用?

2 个答案:

答案 0 :(得分:1)

尝试在angular2中使用SimpleChanges

import { SimpleChanges } from '@angular/core'
ngOnChanges(changes: SimpleChanges) {
    console.log(changes);// to log if any changes are detected.

}

可能的错误

  1. 您的 this.selected 不是输入属性
  2. 注意:Angular会在检测到组件(或指令)的输入属性发生更改时调用其 ngOnChanges 方法。

    或者,如果您使用[ngModel] 将变量分配给某个DOM元素,则可以手动触发(ngModelChange)事件。

    <input type="text" [ngModel]="selected" (ngModelChange)="onSelectedChange($event)" />
    

    您需要将方法处理为

    onSelectedChange(val){
         .....
    }
    

    最佳实践

    在处理 @output 属性的所有其他替代方案中,您正在使用组件中的方法,您可以将所有逻辑放入该方法本身而不是使用上述。

    查看 ngDoCheck ChangeDetectionStrategy 以检测您可以使用的所有更改 this answer of mine 。但是 ngDoCheck()检查鼠标和键盘事件会导致很大的开销。

答案 1 :(得分:0)

如果你想渲染单选按钮列表,并在用户点击答案时处理点击事件,我会这样设置:

<强>接口

interface Choice {
    id:number,
    name:string;
}

interface Question {
    text: string;
    choices: Choice[];
}

子组件

@Component({
    moduleId: module.id,
    selector: 'child',
    template: `
        <div>
            {{ question.text }}
        </div>

        <div *ngFor="let option of question.choices">
            <input type="radio" (click)="selectOption(option)" name="options" [value]="option.id">{{option.name}}<br>
       </div>

    `
})
export class ChildComponent {
    @Input() question: Question;
    @Output() selected: EventEmitter<Choice>;
    constructor() {
        this.selected = new EventEmitter<Choice>();
    }

    selectOption(choice:Choice) {
        this.selected.next(choice);
    }
}

父组件

@Component({
    moduleId: module.id,
    selector: 'parent',
    template: `
        Options: 
        <child [question]="question" (selected)="onSelect($event)" ></child>
    `
})
export class ParentComponent {
    question: Question;
    constructor() {
        this.question = {
            text: "what is 1+1?",
            choices: [
                { id: 1, name: 'Choice 1'}, 
                { id: 2, name: 'Choice 2'}, 
                { id: 3, name: 'Choice 4'}, 
                { id: 4, name: 'Choice 8'} 
            ]
        };
    }

    onSelect(choice:Choice) {
        alert(choice.id);
    }

}

希望这有帮助!