Изменение свойств ввода в Angular после fixture.detectChanges (), приводящее к странному поведению - PullRequest
1 голос
/ 10 апреля 2020

Предположим, есть 2 компонента: AppComponent и TestComponent. Я звоню в TestComponent, используя его директиву в шаблоне HTML AppComponent. Теперь TestComponent имеет свойство @Input () (пусть это будет myTitle).

Я занимаюсь модульным тестированием только для TestComponent. Для заголовка я передаю случайное значение в самом тесте. Вот код для того же:

app.component. html

<span><app-test [myTitle]="title"></app-test></span>

app.component.ts

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent{
    title = {name: 'hello-world'};
}

test.component. html

<p>test works!!{{myTitle.name}}</p>

test.component.ts

@Component({
    selector: 'app-test',
    templateUrl: './test.component.html',
    styleUrls: ['./test.component.css']
})

export class TestComponent implements OnInit{
    @Input() myTitle;

    constructor(){

    }

    ngOnInit():void{
        this.myTitle.name = "Hi!!";
    }
}

test.component.spe c .ts

describe('Test component',() =>{
    let temp;
    let component: TestComponent;
    let fixture: ComponentFixture<TestComponent>;

    beforeEach(async(() =>{
       TestBed.configureTestingModule({
           declarations: [TestComponent],
           schemas: [NO_ERRORS_SCHEMA]
       }) 
       .compileComponents();
    }));

    beforeEach(()=>{
        temp = {name: "Heloooo"};
       fixture = TestBed.createComponent(TestComponent);
       component = fixture.componentInstance;
    });

    it('should check First',()=>{
       component.myTitle = temp;
       console.log(component.myTitle.name);
       console.log(temp.name);

       fixture.detectChanges();

       console.log(component.myTitle.name);
       console.log(temp.name);
       expect(component.myTitle.name).toEqual(temp.name);
    });

    it('should check Second',()=>{
       component.myTitle = temp;
       console.log(component.myTitle.name);
       console.log(temp.name);

       fixture.detectChanges();

       temp.name = "Majin Buu";
       console.log(component.myTitle.name);
       console.log(temp.name);
       expect(component.myTitle.name).toEqual(temp.name);
    });
});

И тест пройден, и я не не знаю причину почему.

Вопросы:

  1. Здесь предположим, что свойство input представляет собой простую строку вместо объекта, тогда случаи терпеть неудачу, чего я и ожидал. Но для объектов это не работает.

  2. Файл console.log, который я написал, дает следующий вывод:

Контрольный пример 1:

Heloooo          
Heloooo               
Hi!!          
Hi!!      

Контрольный пример 2:

Heloooo       
Heloooo             
Majin Buu     
Majin Buu     

Почему он показывает последнее значение для object.name? Я думал, что объект

temp

является локальным для этого сценария.

Является ли fixture.detectChanges () только для вызова ngOnInit? Если нет, то как это работает? И как сделать так, чтобы контрольные примеры также не выполнялись для объектов?

Я новичок в этом сообществе, поэтому, пожалуйста, помогите мне улучшить вопрос, если есть какие-либо ошибки.

1 Ответ

0 голосов
/ 10 апреля 2020

Когда вы назначаете объект другому объекту. Изменяется только ссылка, а не адрес кучи этого объекта.

Так что здесь temp - это объект, который вы назначаете myTitle, myTitle и temp, ссылающиеся на один и тот же объект, означают любое изменение в этом объекте. будет отражаться как myTitle, так и temp.

В тестовом примере 2, когда вы изменяете значение temp, вы обновляете значение объекта, на которое также ссылается myTitle. Вот почему это проходит

temp: object | Array // will get change properties value
temp:number | string | boolean // will not change.
fixture.detectChanges () не означает запуск ngOnInit (). Используется для указания Angular запустить обнаружение изменений
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...