如何解决:无法在Angular 6中设置null错误的属性“ innerHTML”?

时间:2018-12-24 19:44:23

标签: angular typescript

我想在我的应用中创建自定义日历。在 JavaScript 中开发代码时,它可以正常工作。当我尝试将代码迁移到Angular 6之后,它无法正常工作。 Angular抛出运行时错误。我无法解决,

任何人都可以帮助我!

这是我正在使用的Stack-Blitz链接:StackBlitz

showCalendar(month, year) {
const firstDay = (new Date(year, month)).getDay();
const daysInMonth = 32 - new Date(year, month, 32).getDate();

console.log('\n val \n' + new Date(year, month, 32).getDate());

const tbl = document.getElementById('calendar-body');

// clearing all previous cells
tbl.innerHTML = '';

// filing data about month and in the page via DOM.
this.monthAndYear.innerHTML = this.months[month] + ' ' + year;

 // creating all cells
let date = 1;
for (let i = 0; i < 6; i++) {
    const row = document.createElement('tr');

    for (let j = 0; j < 7; j++) {
        // let cell = document.createElement('td');
        if (i === 0 && j < firstDay) {
            const cell = document.createElement('td');
            const cellText = document.createTextNode('');
            cell.appendChild(cellText);
            row.appendChild(cell);
        } else if (date > daysInMonth) {
            break;
        } else {
            const cell = document.createElement('td');
            const cellText = document.createTextNode(date.toString());
        if (date === this.today.getDate() && year === this.today.getFullYear() && month === this.today.getMonth()) {
            // cell.classList.add("bg-info");
        } // color todays date
            date++;
        }
    }
    tbl.appendChild(row); // appending each row into calendar body.
  }
}

constructor() {
 this.today = new Date();
 this.currentMonth = this.today.getMonth();
 this.currentYear = this.today.getFullYear();
 this.monthAndYear = document.getElementById('monthAndYear');
}

ngOnInit() {
 this.showCalendar(this.currentMonth, this.currentYear);
 console.log('ngOnInit');
}

预期结果是显示日历。

但是它给出错误为: ERROR TypeError: Cannot set property 'innerHTML' of null at CustomCalendarComponent.push../src/app/components/custom-calendar/custom-calendar.component.ts.CustomCalendarComponent.showCalendar (custom-calendar.component.ts:67)

2 个答案:

答案 0 :(得分:1)

document.getElementByid('monthAndYear')移动到ngOnInit,因为在调用构造函数时尚无附加的DOM。

https://stackblitz.com/edit/angular-yzzvsb?file=src/app/app.component.ts

此外,整个日历生成逻辑都已损坏,因此您必须对其进行处理。添加行和单元格。但是,为什么将它们设置为空是一个谜。

答案 1 :(得分:1)

Angular使用单独的API来操作DOM.Angular提供的Renderer2以一种服务的形式提供,该服务允许在不直接接触DOM的情况下操作应用程序的元素

如果要使用模板变量从DOM中选择特定元素,请使用ViewChild装饰器访问组件类中的元素

component.html

<h3 class="card-reader" id="monthAndYear" #monthAndYear> Month and Year</h3>

component.ts

@ViewChild('monthAndYear') monthAndYear: ElementRef;

使用Renderer2创建新元素

      constructor(private ren: Renderer2) {}
      const cell = this.ren.createElement('td');
      const cellText = this.ren.createText('');
      cell.appendChild(cellText);

参考:https://alligator.io/angular/using-renderer2/

派生示例:https://stackblitz.com/edit/angular-up1ibg