1

我想在我的应用程序中创建一个自定义日历。在用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)

4

2 回答 2

1

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

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

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

于 2018-12-24T20:34:52.737 回答
1

Angular 使用单独的 API 来操作 DOM。Angular 以服务的形式提供的 Renderer2 允许操作应用程序的元素而无需直接接触 DOM

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

组件.html

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

组件.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

于 2018-12-25T03:52:04.467 回答