Select 如何在Angular(v9,Material)中导出或获取*ngFor循环外部的局部变量

Select 如何在Angular(v9,Material)中导出或获取*ngFor循环外部的局部变量,select,angular-material,global-variables,custom-data-attribute,angular-ngfor,Select,Angular Material,Global Variables,Custom Data Attribute,Angular Ngfor,角度的第一步(材质为版本9)。我正在使用以下代码创建表单: HTML: <mat-form-field> <mat-label>Course</mat-label> <mat-select [formControl]="subjectControl" [attr.data-tag-subjectSemester]="this.subjectControl.value

角度的第一步(材质为版本9)。我正在使用以下代码创建表单:

HTML:

<mat-form-field>
    <mat-label>Course</mat-label>
        <mat-select
            [formControl]="subjectControl"
            [attr.data-tag-subjectSemester]="this.subjectControl.value
                ? this.subjectControl.value.trim()
                : ''
            [attr.data-tag-subjectName]="this.subjectControl.value
                ? this.subjectControl.value.trim()
                : ''
            (selectionChange)="onChange($event)"
            required
        >
            <mat-option>-- None --</mat-option>
            <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
                <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester"><!--For now, here I have to set `[value]` to `.subjectName` OR `.subjectSemester` to show it into the `data-tag`, but the question is How to export BOTH variables outside the `*ngFor` loop, if I can choose only one variable as option to show it as value?-->
                    {{ subject.subjectName }}
                </mat-option>
            </mat-optgroup>
        </mat-select>
        <mat-hint>
            {{
                this.subjectControl.value
                    ? this.subjectControl.value.trim()
                    : ''
            }}
        </mat-hint>
</mat-form-field>
export interface SubjectGroup {
    disabled?: boolean;
    semester: string;
    courses: Subject[];
}
export interface Subject {
    subjectName: string;
    subjectSemester: string;
}

subjectControl = new FormControl("", Validators.required);
export class FormComponent implements OnInit {
    subjectControl = new FormControl("", Validators.required);
    subjects: SubjectGroup[] = [
        {
            disabled: false,
            semester: "Semester 1",
            courses: [
                {
                    subjectName: "Course 1",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 2",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 3",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 4",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 5",
                    subjectSemester: "1° Semester"
                }
            ]
        },
        {
            disabled: false,
            semester: "Semester 2",
            courses: [
                {
                    subjectName: "Course 1",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 2",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 3",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 4",
                    subjectSemester: "2° Semester"
                }
            ]
        }
    ];
}

onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value; /* here I would to export both subjectName and subjectSemester; I tried in a way like `let subjectSemester = this.subjectControl.value?.subjectSemester;` and `let subjectName = this.subjectControl.value?.subjectName;`, but I can't get it! What I'm doing wrong?*/
    alert(subjectSemester);
}
onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value?.subjectSemester;
    let subjectName = this.subjectControl.value?.subjectName;
    alert(subjectName + ", " + subjectSemester);
}
<mat-form-field>
    <mat-label>Course</mat-label>
        <mat-select
            [formControl]="subjectControl"
            [attr.data-tag-subjectSemester]="this.subjectControl.value?.subjectSemester
                ? this.subjectControl.value?.subjectSemester.trim()
                : ''
            [attr.data-tag-subjectName]="this.subjectControl.value.?subjectName
                ? this.subjectControl.value?.subjectName.trim()
                : ''
            (selectionChange)="onChange($event)"
            required
        >
            <mat-option>-- None --</mat-option>
            <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
                <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester">
                    {{ subject.subjectName }}
                </mat-option>
            </mat-optgroup>
        </mat-select>
        <mat-hint>
            {{
                this.subjectControl.value?.subjectSemester
                    ? this.subjectControl.value?.subjectSemester.trim()
                    : ''
            }}
        </mat-hint>
</mat-form-field>
onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value?.subjectSemester;
    let subjectName = this.subjectControl.value?.subjectName;
    alert(subjectName + ", " + subjectSemester);
}
<mat-form-field>
    <mat-label>Course</mat-label>
    <mat-select
        id="subjectSelector"
        [formControl]="subjectControl"
        (selectionChange)="onChange($event)"
        required
    >
        <mat-option>-- None --</mat-option>
        <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
            <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester">
                {{ subject.subjectName }}
            </mat-option>
        </mat-optgroup>
    </mat-select>
</mat-form-field>
onChange(event: any) {
    if (event.source.selected === undefined) {
        document
            .getElementById("subjectSelector")
            .setAttribute("data-tag-subjectName", "subjectNone");
        document
            .getElementById("subjectSelector")
            .setAttribute("data-tag-subjectSemester", "semesterNone");
    } else {
        let target = event.source.selected._element.nativeElement;
        let selectedData = {
            fieldId: target.getAttribute("id"),
            Semester: event.value,
            Name: target.innerText.trim()
        };
        //console.log(selectedData);
        //alert(selectedData.Semester);
        //alert(selectedData.Name);
        document
            .getElementById("subjectSelector")
            .setAttribute(
                "data-tag-subjectName", selectedData.Name.trim()
            );
        document
            .getElementById("subjectSelector")
            .setAttribute(
                "data-tag-subjectSemester", selectedData.Semester.trim()
            );
    }
}
上面的代码没有返回正确的
数据标记subjectName
属性,因为我将
[value]
设置为
subject.subjectSerment
到HTML代码的
mat选项中。

如代码注释中所述,我希望导出所选选项的
*ngFor
循环之外的
subjectSemment
subjectName
(属于TS
对象的
),以将它们存储在相应的数据属性中(例如,
数据标记subjectSerm
数据标记subjectName
),并在我的模板中使用它们作为
标签和/或
mat-hint
,但由于某种原因我不能这样做,例如:

TS:

<mat-form-field>
    <mat-label>Course</mat-label>
        <mat-select
            [formControl]="subjectControl"
            [attr.data-tag-subjectSemester]="this.subjectControl.value
                ? this.subjectControl.value.trim()
                : ''
            [attr.data-tag-subjectName]="this.subjectControl.value
                ? this.subjectControl.value.trim()
                : ''
            (selectionChange)="onChange($event)"
            required
        >
            <mat-option>-- None --</mat-option>
            <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
                <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester"><!--For now, here I have to set `[value]` to `.subjectName` OR `.subjectSemester` to show it into the `data-tag`, but the question is How to export BOTH variables outside the `*ngFor` loop, if I can choose only one variable as option to show it as value?-->
                    {{ subject.subjectName }}
                </mat-option>
            </mat-optgroup>
        </mat-select>
        <mat-hint>
            {{
                this.subjectControl.value
                    ? this.subjectControl.value.trim()
                    : ''
            }}
        </mat-hint>
</mat-form-field>
export interface SubjectGroup {
    disabled?: boolean;
    semester: string;
    courses: Subject[];
}
export interface Subject {
    subjectName: string;
    subjectSemester: string;
}

subjectControl = new FormControl("", Validators.required);
export class FormComponent implements OnInit {
    subjectControl = new FormControl("", Validators.required);
    subjects: SubjectGroup[] = [
        {
            disabled: false,
            semester: "Semester 1",
            courses: [
                {
                    subjectName: "Course 1",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 2",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 3",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 4",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 5",
                    subjectSemester: "1° Semester"
                }
            ]
        },
        {
            disabled: false,
            semester: "Semester 2",
            courses: [
                {
                    subjectName: "Course 1",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 2",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 3",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 4",
                    subjectSemester: "2° Semester"
                }
            ]
        }
    ];
}

onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value; /* here I would to export both subjectName and subjectSemester; I tried in a way like `let subjectSemester = this.subjectControl.value?.subjectSemester;` and `let subjectName = this.subjectControl.value?.subjectName;`, but I can't get it! What I'm doing wrong?*/
    alert(subjectSemester);
}
onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value?.subjectSemester;
    let subjectName = this.subjectControl.value?.subjectName;
    alert(subjectName + ", " + subjectSemester);
}
<mat-form-field>
    <mat-label>Course</mat-label>
        <mat-select
            [formControl]="subjectControl"
            [attr.data-tag-subjectSemester]="this.subjectControl.value?.subjectSemester
                ? this.subjectControl.value?.subjectSemester.trim()
                : ''
            [attr.data-tag-subjectName]="this.subjectControl.value.?subjectName
                ? this.subjectControl.value?.subjectName.trim()
                : ''
            (selectionChange)="onChange($event)"
            required
        >
            <mat-option>-- None --</mat-option>
            <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
                <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester">
                    {{ subject.subjectName }}
                </mat-option>
            </mat-optgroup>
        </mat-select>
        <mat-hint>
            {{
                this.subjectControl.value?.subjectSemester
                    ? this.subjectControl.value?.subjectSemester.trim()
                    : ''
            }}
        </mat-hint>
</mat-form-field>
onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value?.subjectSemester;
    let subjectName = this.subjectControl.value?.subjectName;
    alert(subjectName + ", " + subjectSemester);
}
<mat-form-field>
    <mat-label>Course</mat-label>
    <mat-select
        id="subjectSelector"
        [formControl]="subjectControl"
        (selectionChange)="onChange($event)"
        required
    >
        <mat-option>-- None --</mat-option>
        <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
            <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester">
                {{ subject.subjectName }}
            </mat-option>
        </mat-optgroup>
    </mat-select>
</mat-form-field>
onChange(event: any) {
    if (event.source.selected === undefined) {
        document
            .getElementById("subjectSelector")
            .setAttribute("data-tag-subjectName", "subjectNone");
        document
            .getElementById("subjectSelector")
            .setAttribute("data-tag-subjectSemester", "semesterNone");
    } else {
        let target = event.source.selected._element.nativeElement;
        let selectedData = {
            fieldId: target.getAttribute("id"),
            Semester: event.value,
            Name: target.innerText.trim()
        };
        //console.log(selectedData);
        //alert(selectedData.Semester);
        //alert(selectedData.Name);
        document
            .getElementById("subjectSelector")
            .setAttribute(
                "data-tag-subjectName", selectedData.Name.trim()
            );
        document
            .getElementById("subjectSelector")
            .setAttribute(
                "data-tag-subjectSemester", selectedData.Semester.trim()
            );
    }
}
我试图使用
[ngValue]=“subject”更改代码
对于
mat选项
到HTML代码中,将
导出为
对象
尝试选择想要的变量,就像上面修改的上次
onChange
函数一样,但通过这种方式,我获得了
未定义的
变量以及表单中的空字段

理想情况下,我想让以下代码正常工作:

<mat-form-field>
    <mat-label>Course</mat-label>
        <mat-select
            [formControl]="subjectControl"
            [attr.data-tag-subjectSemester]="this.subjectControl.value
                ? this.subjectControl.value.trim()
                : ''
            [attr.data-tag-subjectName]="this.subjectControl.value
                ? this.subjectControl.value.trim()
                : ''
            (selectionChange)="onChange($event)"
            required
        >
            <mat-option>-- None --</mat-option>
            <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
                <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester"><!--For now, here I have to set `[value]` to `.subjectName` OR `.subjectSemester` to show it into the `data-tag`, but the question is How to export BOTH variables outside the `*ngFor` loop, if I can choose only one variable as option to show it as value?-->
                    {{ subject.subjectName }}
                </mat-option>
            </mat-optgroup>
        </mat-select>
        <mat-hint>
            {{
                this.subjectControl.value
                    ? this.subjectControl.value.trim()
                    : ''
            }}
        </mat-hint>
</mat-form-field>
export interface SubjectGroup {
    disabled?: boolean;
    semester: string;
    courses: Subject[];
}
export interface Subject {
    subjectName: string;
    subjectSemester: string;
}

subjectControl = new FormControl("", Validators.required);
export class FormComponent implements OnInit {
    subjectControl = new FormControl("", Validators.required);
    subjects: SubjectGroup[] = [
        {
            disabled: false,
            semester: "Semester 1",
            courses: [
                {
                    subjectName: "Course 1",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 2",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 3",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 4",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 5",
                    subjectSemester: "1° Semester"
                }
            ]
        },
        {
            disabled: false,
            semester: "Semester 2",
            courses: [
                {
                    subjectName: "Course 1",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 2",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 3",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 4",
                    subjectSemester: "2° Semester"
                }
            ]
        }
    ];
}

onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value; /* here I would to export both subjectName and subjectSemester; I tried in a way like `let subjectSemester = this.subjectControl.value?.subjectSemester;` and `let subjectName = this.subjectControl.value?.subjectName;`, but I can't get it! What I'm doing wrong?*/
    alert(subjectSemester);
}
onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value?.subjectSemester;
    let subjectName = this.subjectControl.value?.subjectName;
    alert(subjectName + ", " + subjectSemester);
}
<mat-form-field>
    <mat-label>Course</mat-label>
        <mat-select
            [formControl]="subjectControl"
            [attr.data-tag-subjectSemester]="this.subjectControl.value?.subjectSemester
                ? this.subjectControl.value?.subjectSemester.trim()
                : ''
            [attr.data-tag-subjectName]="this.subjectControl.value.?subjectName
                ? this.subjectControl.value?.subjectName.trim()
                : ''
            (selectionChange)="onChange($event)"
            required
        >
            <mat-option>-- None --</mat-option>
            <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
                <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester">
                    {{ subject.subjectName }}
                </mat-option>
            </mat-optgroup>
        </mat-select>
        <mat-hint>
            {{
                this.subjectControl.value?.subjectSemester
                    ? this.subjectControl.value?.subjectSemester.trim()
                    : ''
            }}
        </mat-hint>
</mat-form-field>
onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value?.subjectSemester;
    let subjectName = this.subjectControl.value?.subjectName;
    alert(subjectName + ", " + subjectSemester);
}
<mat-form-field>
    <mat-label>Course</mat-label>
    <mat-select
        id="subjectSelector"
        [formControl]="subjectControl"
        (selectionChange)="onChange($event)"
        required
    >
        <mat-option>-- None --</mat-option>
        <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
            <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester">
                {{ subject.subjectName }}
            </mat-option>
        </mat-optgroup>
    </mat-select>
</mat-form-field>
onChange(event: any) {
    if (event.source.selected === undefined) {
        document
            .getElementById("subjectSelector")
            .setAttribute("data-tag-subjectName", "subjectNone");
        document
            .getElementById("subjectSelector")
            .setAttribute("data-tag-subjectSemester", "semesterNone");
    } else {
        let target = event.source.selected._element.nativeElement;
        let selectedData = {
            fieldId: target.getAttribute("id"),
            Semester: event.value,
            Name: target.innerText.trim()
        };
        //console.log(selectedData);
        //alert(selectedData.Semester);
        //alert(selectedData.Name);
        document
            .getElementById("subjectSelector")
            .setAttribute(
                "data-tag-subjectName", selectedData.Name.trim()
            );
        document
            .getElementById("subjectSelector")
            .setAttribute(
                "data-tag-subjectSemester", selectedData.Semester.trim()
            );
    }
}
HTML:

<mat-form-field>
    <mat-label>Course</mat-label>
        <mat-select
            [formControl]="subjectControl"
            [attr.data-tag-subjectSemester]="this.subjectControl.value
                ? this.subjectControl.value.trim()
                : ''
            [attr.data-tag-subjectName]="this.subjectControl.value
                ? this.subjectControl.value.trim()
                : ''
            (selectionChange)="onChange($event)"
            required
        >
            <mat-option>-- None --</mat-option>
            <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
                <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester"><!--For now, here I have to set `[value]` to `.subjectName` OR `.subjectSemester` to show it into the `data-tag`, but the question is How to export BOTH variables outside the `*ngFor` loop, if I can choose only one variable as option to show it as value?-->
                    {{ subject.subjectName }}
                </mat-option>
            </mat-optgroup>
        </mat-select>
        <mat-hint>
            {{
                this.subjectControl.value
                    ? this.subjectControl.value.trim()
                    : ''
            }}
        </mat-hint>
</mat-form-field>
export interface SubjectGroup {
    disabled?: boolean;
    semester: string;
    courses: Subject[];
}
export interface Subject {
    subjectName: string;
    subjectSemester: string;
}

subjectControl = new FormControl("", Validators.required);
export class FormComponent implements OnInit {
    subjectControl = new FormControl("", Validators.required);
    subjects: SubjectGroup[] = [
        {
            disabled: false,
            semester: "Semester 1",
            courses: [
                {
                    subjectName: "Course 1",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 2",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 3",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 4",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 5",
                    subjectSemester: "1° Semester"
                }
            ]
        },
        {
            disabled: false,
            semester: "Semester 2",
            courses: [
                {
                    subjectName: "Course 1",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 2",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 3",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 4",
                    subjectSemester: "2° Semester"
                }
            ]
        }
    ];
}

onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value; /* here I would to export both subjectName and subjectSemester; I tried in a way like `let subjectSemester = this.subjectControl.value?.subjectSemester;` and `let subjectName = this.subjectControl.value?.subjectName;`, but I can't get it! What I'm doing wrong?*/
    alert(subjectSemester);
}
onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value?.subjectSemester;
    let subjectName = this.subjectControl.value?.subjectName;
    alert(subjectName + ", " + subjectSemester);
}
<mat-form-field>
    <mat-label>Course</mat-label>
        <mat-select
            [formControl]="subjectControl"
            [attr.data-tag-subjectSemester]="this.subjectControl.value?.subjectSemester
                ? this.subjectControl.value?.subjectSemester.trim()
                : ''
            [attr.data-tag-subjectName]="this.subjectControl.value.?subjectName
                ? this.subjectControl.value?.subjectName.trim()
                : ''
            (selectionChange)="onChange($event)"
            required
        >
            <mat-option>-- None --</mat-option>
            <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
                <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester">
                    {{ subject.subjectName }}
                </mat-option>
            </mat-optgroup>
        </mat-select>
        <mat-hint>
            {{
                this.subjectControl.value?.subjectSemester
                    ? this.subjectControl.value?.subjectSemester.trim()
                    : ''
            }}
        </mat-hint>
</mat-form-field>
onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value?.subjectSemester;
    let subjectName = this.subjectControl.value?.subjectName;
    alert(subjectName + ", " + subjectSemester);
}
<mat-form-field>
    <mat-label>Course</mat-label>
    <mat-select
        id="subjectSelector"
        [formControl]="subjectControl"
        (selectionChange)="onChange($event)"
        required
    >
        <mat-option>-- None --</mat-option>
        <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
            <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester">
                {{ subject.subjectName }}
            </mat-option>
        </mat-optgroup>
    </mat-select>
</mat-form-field>
onChange(event: any) {
    if (event.source.selected === undefined) {
        document
            .getElementById("subjectSelector")
            .setAttribute("data-tag-subjectName", "subjectNone");
        document
            .getElementById("subjectSelector")
            .setAttribute("data-tag-subjectSemester", "semesterNone");
    } else {
        let target = event.source.selected._element.nativeElement;
        let selectedData = {
            fieldId: target.getAttribute("id"),
            Semester: event.value,
            Name: target.innerText.trim()
        };
        //console.log(selectedData);
        //alert(selectedData.Semester);
        //alert(selectedData.Name);
        document
            .getElementById("subjectSelector")
            .setAttribute(
                "data-tag-subjectName", selectedData.Name.trim()
            );
        document
            .getElementById("subjectSelector")
            .setAttribute(
                "data-tag-subjectSemester", selectedData.Semester.trim()
            );
    }
}

希望了解我做错了什么,非常感谢。

找到了解决方案,直到找到更好的解决方案:

HTML:

<mat-form-field>
    <mat-label>Course</mat-label>
        <mat-select
            [formControl]="subjectControl"
            [attr.data-tag-subjectSemester]="this.subjectControl.value
                ? this.subjectControl.value.trim()
                : ''
            [attr.data-tag-subjectName]="this.subjectControl.value
                ? this.subjectControl.value.trim()
                : ''
            (selectionChange)="onChange($event)"
            required
        >
            <mat-option>-- None --</mat-option>
            <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
                <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester"><!--For now, here I have to set `[value]` to `.subjectName` OR `.subjectSemester` to show it into the `data-tag`, but the question is How to export BOTH variables outside the `*ngFor` loop, if I can choose only one variable as option to show it as value?-->
                    {{ subject.subjectName }}
                </mat-option>
            </mat-optgroup>
        </mat-select>
        <mat-hint>
            {{
                this.subjectControl.value
                    ? this.subjectControl.value.trim()
                    : ''
            }}
        </mat-hint>
</mat-form-field>
export interface SubjectGroup {
    disabled?: boolean;
    semester: string;
    courses: Subject[];
}
export interface Subject {
    subjectName: string;
    subjectSemester: string;
}

subjectControl = new FormControl("", Validators.required);
export class FormComponent implements OnInit {
    subjectControl = new FormControl("", Validators.required);
    subjects: SubjectGroup[] = [
        {
            disabled: false,
            semester: "Semester 1",
            courses: [
                {
                    subjectName: "Course 1",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 2",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 3",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 4",
                    subjectSemester: "1° Semester"
                },
                {
                    subjectName: "Course 5",
                    subjectSemester: "1° Semester"
                }
            ]
        },
        {
            disabled: false,
            semester: "Semester 2",
            courses: [
                {
                    subjectName: "Course 1",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 2",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 3",
                    subjectSemester: "2° Semester"
                },
                {
                    subjectName: "Course 4",
                    subjectSemester: "2° Semester"
                }
            ]
        }
    ];
}

onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value; /* here I would to export both subjectName and subjectSemester; I tried in a way like `let subjectSemester = this.subjectControl.value?.subjectSemester;` and `let subjectName = this.subjectControl.value?.subjectName;`, but I can't get it! What I'm doing wrong?*/
    alert(subjectSemester);
}
onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value?.subjectSemester;
    let subjectName = this.subjectControl.value?.subjectName;
    alert(subjectName + ", " + subjectSemester);
}
<mat-form-field>
    <mat-label>Course</mat-label>
        <mat-select
            [formControl]="subjectControl"
            [attr.data-tag-subjectSemester]="this.subjectControl.value?.subjectSemester
                ? this.subjectControl.value?.subjectSemester.trim()
                : ''
            [attr.data-tag-subjectName]="this.subjectControl.value.?subjectName
                ? this.subjectControl.value?.subjectName.trim()
                : ''
            (selectionChange)="onChange($event)"
            required
        >
            <mat-option>-- None --</mat-option>
            <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
                <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester">
                    {{ subject.subjectName }}
                </mat-option>
            </mat-optgroup>
        </mat-select>
        <mat-hint>
            {{
                this.subjectControl.value?.subjectSemester
                    ? this.subjectControl.value?.subjectSemester.trim()
                    : ''
            }}
        </mat-hint>
</mat-form-field>
onChange(event: { stopPropagation: () => void }) {
    let subjectSemester = this.subjectControl.value?.subjectSemester;
    let subjectName = this.subjectControl.value?.subjectName;
    alert(subjectName + ", " + subjectSemester);
}
<mat-form-field>
    <mat-label>Course</mat-label>
    <mat-select
        id="subjectSelector"
        [formControl]="subjectControl"
        (selectionChange)="onChange($event)"
        required
    >
        <mat-option>-- None --</mat-option>
        <mat-optgroup *ngFor="let course of subjects" [label]="course.semester" [disabled]="course.disabled">
            <mat-option *ngFor="let subject of course.courses" [value]="subject.subjectSemester">
                {{ subject.subjectName }}
            </mat-option>
        </mat-optgroup>
    </mat-select>
</mat-form-field>
onChange(event: any) {
    if (event.source.selected === undefined) {
        document
            .getElementById("subjectSelector")
            .setAttribute("data-tag-subjectName", "subjectNone");
        document
            .getElementById("subjectSelector")
            .setAttribute("data-tag-subjectSemester", "semesterNone");
    } else {
        let target = event.source.selected._element.nativeElement;
        let selectedData = {
            fieldId: target.getAttribute("id"),
            Semester: event.value,
            Name: target.innerText.trim()
        };
        //console.log(selectedData);
        //alert(selectedData.Semester);
        //alert(selectedData.Name);
        document
            .getElementById("subjectSelector")
            .setAttribute(
                "data-tag-subjectName", selectedData.Name.trim()
            );
        document
            .getElementById("subjectSelector")
            .setAttribute(
                "data-tag-subjectSemester", selectedData.Semester.trim()
            );
    }
}