Angular 如何避免使用Elvis操作符?

Angular 如何避免使用Elvis操作符?,angular,typescript,firebase,firebase-realtime-database,angularfire,Angular,Typescript,Firebase,Firebase Realtime Database,Angularfire,在Angular 2中,我的网站进展得越快,Elvis操作员似乎越是使这一切成为可能的神奇力量。我所采取的每一步都涉及到如何将它正确地应用于数据处理的每一个实例。我觉得,如果你在现实生活中使用实际数据所做的每件事都需要?是“正常的”,那么Angular docs会提到这一点 举个例子,我最近刚刚学习了如何为被动表单设置FormGroups。按照Angular.io上的步骤,我的表单组如下所示 createForm() { this.quesForm = this.fbuild.group

在Angular 2中,我的网站进展得越快,
Elvis操作员
似乎越是使这一切成为可能的神奇力量。我所采取的每一步都涉及到如何将它正确地应用于数据处理的每一个实例。我觉得,如果你在现实生活中使用实际数据所做的每件事都需要
是“正常的”,那么Angular docs会提到这一点

举个例子,我最近刚刚学习了如何为被动表单设置
FormGroups
。按照Angular.io上的步骤,我的表单组如下所示

createForm() {
    this.quesForm = this.fbuild.group({
        question: this.featureQuestion.question,
        id      : this.featureQuestion.id,
        name    : this.featureQuestion.name,
        answers : this.fbuild.array([])
    });
    this.setAnswers(this.featureQuestion.answers);
}

get answers(): FormArray {
    return this.quesForm.get('answers') as FormArray;
};
使用我在
const
中创建的
mock数据
工作起来非常好。然而,当我打算用“真实数据”来“真实地使用”它时,我不得不再花3到4天的时间来发现我需要这样做

createForm() {
    this.quesForm = this.fbuild.group({
        question: this.featureQuestion ? this.featureQuestion.question: '',
        id      : this.featureQuestion ? this.featureQuestion.id: '',
        name    : this.featureQuestion ? this.featureQuestion.name: '',
        answers : this.fbuild.array([])
    });
    this.setAnswers(this.featureQuestion ? this.featureQuestion.answers: []);
}
无论是绑定到html、绑定到属性、传递
@Input
@Output
,还是在函数中执行某些操作;猫王接线员是桥上的巨魔,他用了一个疯狂的谜语,花了一个星期的时间才猜出来,只是为了做我认为我已经学会的事情。起初我认为这只是他们必须解决的一个小问题,但现在这对我个人来说太大了,不可能仅仅是一个bug,否则我认为会有更多关于它的信息,因为这意味着没有人能够在现实生活中使用Angular而不在每一步都应用它。这意味着这一定是我正在做的事情

下面是我当前如何从Firebase调用数据的示例

服务

export class HomeService {
    BusImage : FirebaseObjectObservable<any>;

    constructor(private af: AngularFire) {}

    getBusImage() {
        this.BusImage = this.af.database.object('/page_area_business_image')
        as FirebaseObjectObservable<any>

        return this.BusImage;
    }
}
导出类家庭服务{
业务图像:FirebaseObjectObservable;
构造函数(私有af:AngularFire){}
getBusImage(){
this.BusImage=this.af.database.object(“/page\u area\u business\u image”)
可观察到的
返回此.BusImage;
}
}
父组件

export class ExpBusinessComponent implements OnInit {

    private busImageO       : FirebaseObjectObservable<any>;
    private busImageQues01O : FirebaseObjectObservable<any>;
    private busImageQues02O : FirebaseObjectObservable<any>;

    constructor(private _homeService: HomeService) {}

    ngOnInit() {
        this._homeService.getBusImage().subscribe(BusImage => {
            this.busImageO       = BusImage.expand;
            this.busImageQues01O = BusImage.questions.question01;
            this.busImageQues02O = BusImage.questions.question02;
        });
    }
}
export class BusinessImageComponent implements OnChanges, OnInit {
    @Input('busImageI')         busImage    : FirebaseObjectObservable<any>;
    @Input('busImageQues01I')   question01  : FirebaseObjectObservable<any>;
    @Input('busImageQues02I')   question02  : FirebaseObjectObservable<any>;

    public selectedI(selected){ this.selectedAnswer = selected };

    selectedAnswer: any;

    expbTrigger         : boolean = false;
    expb2Trigger        : boolean = false;
}
export class MultipleChoiceRadioComponent implements OnInit, OnChanges {
    @Input('question') featureQuestion: QuestionModel;
    @Output() selectedO: EventEmitter<any> = new EventEmitter();

    selected = {value1: '', value2: ''};

    quesForm: FormGroup;

    public sendAnswer = (): void => {
         this.selectedO.emit(this.selected);
     }

    constructor(private fbuild : FormBuilder) {}

    ngOnChanges() {
        this.createForm();
    }

    createForm() {
        this.quesForm = this.fbuild.group({
            question: this.featureQuestion ? this.featureQuestion.question: '',
            id      : this.featureQuestion ? this.featureQuestion.id: '',
            name    : this.featureQuestion ? this.featureQuestion.name:  '',
            answers : this.fbuild.array([])
        });
        this.setAnswers(this.featureQuestion ? this.featureQuestion.answers: []);
    }

    get answers(): FormArray {
        return this.quesForm.get('answers') as FormArray;
    };

    setAnswers(answers : Answers[]){
        const answersFGs        = answers.map(answers => this.fbuild.group(answers));
        const answersFormArray  = this.fbuild.array(answersFGs);

        this.quesForm.setControl('answers', answersFormArray);
    }

    getSelected(ans) {
        this.selected = { value1: ans.id, value2: ans.answer };

    }
}
导出类ExpBusinessComponent实现OnInit{
私有业务映像:FirebaseObjectObservable;
私有业务mageques1o:FirebaseObjectObservable;
私有businessmageques02o:FirebaseObjectObservable;
构造函数(私有_homeService:homeService){}
恩戈尼尼特(){
这是。_homeService.getBusImage().subscribe(BusImage=>{
this.busImageO=BusImage.expand;
this.busImageQues01O=BusImage.questions.question01;
this.busImageQues02O=BusImage.questions.question02;
});
}
}
父模板

<h1>{{busExpInformation?.title}}</h1>
<p>{{busExpInformation?.intro}}</p>

<business-image
    [busImageI]        =  "busImageO"
    [busImageQues01I]  =  "busImageQues01O"
    [busImageQues02I]  =  "busImageQues02O">
</business-image>
{{busExpInformation?.title}
{{busExpInformation?.intro}}

子组件

export class ExpBusinessComponent implements OnInit {

    private busImageO       : FirebaseObjectObservable<any>;
    private busImageQues01O : FirebaseObjectObservable<any>;
    private busImageQues02O : FirebaseObjectObservable<any>;

    constructor(private _homeService: HomeService) {}

    ngOnInit() {
        this._homeService.getBusImage().subscribe(BusImage => {
            this.busImageO       = BusImage.expand;
            this.busImageQues01O = BusImage.questions.question01;
            this.busImageQues02O = BusImage.questions.question02;
        });
    }
}
export class BusinessImageComponent implements OnChanges, OnInit {
    @Input('busImageI')         busImage    : FirebaseObjectObservable<any>;
    @Input('busImageQues01I')   question01  : FirebaseObjectObservable<any>;
    @Input('busImageQues02I')   question02  : FirebaseObjectObservable<any>;

    public selectedI(selected){ this.selectedAnswer = selected };

    selectedAnswer: any;

    expbTrigger         : boolean = false;
    expb2Trigger        : boolean = false;
}
export class MultipleChoiceRadioComponent implements OnInit, OnChanges {
    @Input('question') featureQuestion: QuestionModel;
    @Output() selectedO: EventEmitter<any> = new EventEmitter();

    selected = {value1: '', value2: ''};

    quesForm: FormGroup;

    public sendAnswer = (): void => {
         this.selectedO.emit(this.selected);
     }

    constructor(private fbuild : FormBuilder) {}

    ngOnChanges() {
        this.createForm();
    }

    createForm() {
        this.quesForm = this.fbuild.group({
            question: this.featureQuestion ? this.featureQuestion.question: '',
            id      : this.featureQuestion ? this.featureQuestion.id: '',
            name    : this.featureQuestion ? this.featureQuestion.name:  '',
            answers : this.fbuild.array([])
        });
        this.setAnswers(this.featureQuestion ? this.featureQuestion.answers: []);
    }

    get answers(): FormArray {
        return this.quesForm.get('answers') as FormArray;
    };

    setAnswers(answers : Answers[]){
        const answersFGs        = answers.map(answers => this.fbuild.group(answers));
        const answersFormArray  = this.fbuild.array(answersFGs);

        this.quesForm.setControl('answers', answersFormArray);
    }

    getSelected(ans) {
        this.selected = { value1: ans.id, value2: ans.answer };

    }
}
导出类BusinessImageComponent实现OnChanges,OnInit{
@输入('busImageI')busImage:FirebaseObjectObservable;
@输入('busImageQues01I')问题01:FirebaseObjectObservable;
@输入('busImageQues02I')问题02:FirebaseObjectObservable;
public selectedI(selected){this.selectedAnswer=selected};
选择答案:任何;
expbTrigger:boolean=false;
expb2Trigger:boolean=false;
}
子模板

<multiple-choice-radio *ngIf="expbTrigger"
    [question]  = "question01"
    (selectedO) = "selectedI($event)"
></multiple-choice-radio>
<form [formGroup]="quesForm" novalidate>
    <fieldset [attr.id]="quesForm.value.id">

        <label>
            {{quesForm.value.question}}
        </label>

        <div>

            <div *ngFor="let ans of quesForm.value.answers">
                <div>

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

                    <label [attr.for]="ans.id">
                        {{ans.answer}}
                    </label>
                </div>
            </div>

        </div>

    </fieldset>
</form>

孙子组件

export class ExpBusinessComponent implements OnInit {

    private busImageO       : FirebaseObjectObservable<any>;
    private busImageQues01O : FirebaseObjectObservable<any>;
    private busImageQues02O : FirebaseObjectObservable<any>;

    constructor(private _homeService: HomeService) {}

    ngOnInit() {
        this._homeService.getBusImage().subscribe(BusImage => {
            this.busImageO       = BusImage.expand;
            this.busImageQues01O = BusImage.questions.question01;
            this.busImageQues02O = BusImage.questions.question02;
        });
    }
}
export class BusinessImageComponent implements OnChanges, OnInit {
    @Input('busImageI')         busImage    : FirebaseObjectObservable<any>;
    @Input('busImageQues01I')   question01  : FirebaseObjectObservable<any>;
    @Input('busImageQues02I')   question02  : FirebaseObjectObservable<any>;

    public selectedI(selected){ this.selectedAnswer = selected };

    selectedAnswer: any;

    expbTrigger         : boolean = false;
    expb2Trigger        : boolean = false;
}
export class MultipleChoiceRadioComponent implements OnInit, OnChanges {
    @Input('question') featureQuestion: QuestionModel;
    @Output() selectedO: EventEmitter<any> = new EventEmitter();

    selected = {value1: '', value2: ''};

    quesForm: FormGroup;

    public sendAnswer = (): void => {
         this.selectedO.emit(this.selected);
     }

    constructor(private fbuild : FormBuilder) {}

    ngOnChanges() {
        this.createForm();
    }

    createForm() {
        this.quesForm = this.fbuild.group({
            question: this.featureQuestion ? this.featureQuestion.question: '',
            id      : this.featureQuestion ? this.featureQuestion.id: '',
            name    : this.featureQuestion ? this.featureQuestion.name:  '',
            answers : this.fbuild.array([])
        });
        this.setAnswers(this.featureQuestion ? this.featureQuestion.answers: []);
    }

    get answers(): FormArray {
        return this.quesForm.get('answers') as FormArray;
    };

    setAnswers(answers : Answers[]){
        const answersFGs        = answers.map(answers => this.fbuild.group(answers));
        const answersFormArray  = this.fbuild.array(answersFGs);

        this.quesForm.setControl('answers', answersFormArray);
    }

    getSelected(ans) {
        this.selected = { value1: ans.id, value2: ans.answer };

    }
}
导出类MultipleChiceRadioComponent实现OnInit、OnChanges{
@输入(“问题”)特征问题:问题模型;
@Output()选择do:EventEmitter=neweventemitter();
所选={value1:'',value2:''};
问题形式:FormGroup;
public sendAnswer=():void=>{
this.selectedO.emit(this.selected);
}
构造函数(私有fbuild:FormBuilder){}
ngOnChanges(){
这个.createForm();
}
createForm(){
this.quesForm=this.fbuild.group({
问题:this.featureQuestion?this.featureQuestion.question:“”,
id:this.featureQuestion?this.featureQuestion.id:“”,
名称:this.featureQuestion?this.featureQuestion.name:“”,
回答:this.fbuild.array([])
});
this.setAnswers(this.featureQuestion?this.featureQuestion.answers:[]);
}
获取答案():FormArray{
将此.quesForm.get('answers')作为FormArray返回;
};
设置答案(答案:答案[]){
const answersFGs=answers.map(answers=>this.fbuild.group(answers));
const answersFormArray=this.fbuild.array(answersFGs);
this.quesForm.setControl('answers',answersFormArray);
}
getSelected(ans){
this.selected={value1:ans.id,value2:ans.answer};
}
}
孙子模板

<multiple-choice-radio *ngIf="expbTrigger"
    [question]  = "question01"
    (selectedO) = "selectedI($event)"
></multiple-choice-radio>
<form [formGroup]="quesForm" novalidate>
    <fieldset [attr.id]="quesForm.value.id">

        <label>
            {{quesForm.value.question}}
        </label>

        <div>

            <div *ngFor="let ans of quesForm.value.answers">
                <div>

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

                    <label [attr.for]="ans.id">
                        {{ans.answer}}
                    </label>
                </div>
            </div>

        </div>

    </fieldset>
</form>

{{quesForm.value.question}
{{ans.answer}}
我刚才提供的大部分代码都被省略了,以消除那些基本上完全相同的过程,只是不同的数据要去不同的地方,我还从HTML中删除了类,因为我使用的是引导,这会使编码变得混乱

到目前为止,
@Output
将所选值发送到父对象只会在我使用
|json
管道对整个对象进行的一些测试绑定中给出结果,但会记录为未定义,因此如果您觉得我这样做有问题,我已经知道它工作不正常

我之所以以这种方式做事,除了这是我唯一能定义
的方法之外,是因为
孙子组件
将在网站的其他地方用于其他问题。有时我只是使用
id
来触发逻辑,有时我将答案拉入将保存到数据库的用户数据实例中。所以对我来说,仅仅将整个模型发送回链上进行extrac是没有意义的