Эта ошибка может быть вызвана только одной из трех вещей:
Вы должны проверить панель Firebug net , чтобы проверить, действительно ли файл загружен правильно. Если нет, он будет подсвечен красным и будет указывать «404» рядом с ним. Если файл загружается должным образом, это означает, что проблема связана с номером 2.
Убедитесь, что весь код jQuery jQuery запущен внутри кодового блока, например:
$(document).ready(function () {
//your code here
});
будет гарантировать, что ваш код будет загружен после инициализации jQuery.
Последнее, что нужно проверить, - убедиться, что вы не загружаете плагины перед загрузкой jQuery. Плагины расширяют объект «$», поэтому, если вы загружаете плагин перед загрузкой ядра jQuery, вы получите описанную вами ошибку.
Примечание. Если вы загружаете код, который не требует jQuery для запустить его не нужно размещать внутри обработчика jQuery. Этот код можно разделить с помощью document.readyState
.
Вы можете использовать следующее:
@Component({
(...)
template: `
<div *ngFor="let i of Arr(num).fill(1)"></div>
`
})
export class SomeComponent {
Arr = Array; //Array type captured in a variable
num:number = 20;
}
Или реализовать пользовательский канал:
import {PipeTransform, Pipe} from '@angular/core';
@Pipe({
name: 'fill'
})
export class FillPipe implements PipeTransform {
transform(value) {
return (new Array(value)).fill(1);
}
}
@Component({
(...)
template: `
<div *ngFor="let i of num | fill"></div>
`,
pipes: [ FillPipe ]
})
export class SomeComponent {
arr:Array;
num:number = 20;
}
Есть две проблемы с рекомендуемыми решениями, использующими Arrays
:
Кажется более эффективным определите Pipe
(один раз), возвращая пример Iterable
:
import {PipeTransform, Pipe} from '@angular/core';
@Pipe({name: 'times'})
export class TimesPipe implements PipeTransform {
transform(value: number): any {
const iterable = {};
iterable[Symbol.iterator] = function* () {
let n = 0;
while (n < value) {
yield ++n;
}
};
return iterable;
}
}
Пример использования (рендеринг сетки с динамической шириной / высотой):
<table>
<thead>
<tr>
<th *ngFor="let x of colCount|times">{{ x }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let y of rowCount|times">
<th scope="row">{{ y }}</th>
<td *ngFor="let x of colCount|times">
<input type="checkbox" checked>
</td>
</tr>
</tbody>
</table>
<div *ngFor="let dummy of ' '.repeat(20).split(''), let x = index">
Замените 20
на свою переменную
Если вы используете Lodash , вы можете сделать следующее:
Импортировать Lodash в ваш компонент.
import * as _ from "lodash";
Объявить переменную-член в компоненте для ссылки на Lodash.
lodash = _;
Тогда, на ваш взгляд, вы можете использовать функцию диапазона . 20 может быть заменен любой переменной в вашем компоненте.
*ngFor="let number of lodash.range(20)"
Надо сказать, что привязка к функциям в представлении может быть дорогостоящей, в зависимости от сложности функции, которую вы вызываете, поскольку обнаружение изменений будет вызовите функцию повторно.
Вы можете просто сделать это в своем HTML:
*ngFor="let number of [0,1,2,3,4,5...,18,19]"
И использовать переменную «число» для индексации.
Упрощенный подход:
Определите helperArray и создайте его динамически (или статически, если хотите) с длиной подсчета, которую вы хотите создать ваши HTML-элементы. Например, я хочу получить некоторые данные с сервера и создать элементы с длиной возвращаемого массива.
export class AppComponent {
helperArray: Array<any>;
constructor(private ss: StatusService) {
}
ngOnInit(): void {
this.ss.getStatusData().subscribe((status: Status[]) => {
this.helperArray = new Array(status.length);
});
}
}
Затем используйте helperArray в моем HTML-шаблоне.
<div class="content-container" *ngFor="let i of helperArray">
<general-information></general-information>
<textfields></textfields>
</div>
Более простое и многоразовое решение, возможно, для использования настраиваемой структурной директивы.
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[appTimes]'
})
export class AppTimesDirective {
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) { }
@Input() set appTimes(times: number) {
for (let i = 0 ; i < times ; i++) {
this.viewContainer.createEmbeddedView(this.templateRef);
}
}
}
И используйте его следующим образом:
<span *appTimes="3" class="fa fa-star"></span>
Вот несколько улучшенная версия структурной директивы Ильяса Ламрани, которая позволяет вам использовать индекс в вашем шаблоне:
@Directive({
selector: '[appRepeatOf]'
})
export class RepeatDirective {
constructor(private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) {
}
@Input()
set appRepeatOf(times: number) {
const initialLength = this.viewContainer.length;
const diff = times - initialLength;
if (diff > 0) {
for (let i = initialLength; i < initialLength + diff; i++) {
this.viewContainer.createEmbeddedView(this.templateRef, {
$implicit: i
});
}
} else {
for (let i = initialLength - 1; i >= initialLength + diff ; i--) {
this.viewContainer.remove(i);
}
}
}
Использование:
<li *appRepeat="let i of myNumberProperty">
Index: {{i}}
</li>