- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
只想说,我认识到有很多与“无法绑定(bind)到 X,因为它不是 Y 的已知属性”错误相关的 SO 帖子。我查看了很多,并找到了一些解决具体问题的答案,但是我很难将其转化为我的案例,我实际上认为这是很笼统的,并且与对的基本误解有关我应该如何解决我的用例。
我正在创建一个 Angular (7) 应用程序,我已将其分成 components
和 routes
. components
是模块化的部分(下拉菜单、模式、按钮等等),并且路由是应用程序中的各个页面。这个术语有点复杂,因为两者在技术上都是 Angular 组件。换句话说,结构(在 src/
内)如下所示:
- app
- components
- dropdown
- dropdown.component.ts
- dropdown.component.html
- dropdown.component.scss
- dropdown.component.spec.ts
- routes
- library
- library.component.ts
- library.component.html
- library.component.scss
- library.component.spec.ts
...
import { Component, OnInit } from '@angular/core';
import { DropdownComponent } from '../../components/dropdown/dropdown.component';
@Component({
selector: 'app-library',
templateUrl: './library.component.html',
styleUrls: ['./library.component.scss']
})
export class LibraryComponent implements OnInit {
pickItem($event) {
console.log($event.item, $event.index);
}
constructor() { }
ngOnInit() {}
}
<div class="library row py4">
<h3 class="typ--geo-bold typ--caps mb5">Style Library</h3>
<div class="mb4" style="max-width: 35rem;">
<p class="typ--geo-bold typ--caps">Dropdowns</p>
<app-dropdown
[items]="['One', 'Two', 'Three']"
(pick)="pickItem($event)"
title="Default dropdown"
></app-dropdown>
<br />
<app-dropdown
[items]="['One', 'Two', 'Three']"
(pick)="pickItem($event)"
title="Inline dropdown"
class="dropdown--inline"
></app-dropdown>
</div>
</div>
items
作为输入——与以下错误相关)。
library.components.spec.ts
但是,测试时,我遇到了以下错误:
Failed: Template parse errors:
Can't bind to 'items' since it isn't a known property of 'app-dropdown'.
1. If 'app-dropdown' is an Angular component and it has 'items' input, then verify that it is part of this module.
2. If 'app-dropdown' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. ("
<p class="typ--geo-bold typ--caps">Dropdowns</p>
<app-dropdown
[ERROR ->][items]="['One', 'Two', 'Three']"
(pick)="pickItem($event)"
title="Default dropdown"
import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { LibraryComponent } from './library.component';
describe('LibraryComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [LibraryComponent],
}).compileComponents();
}));
it('should create the component', () => {
const fixture = TestBed.createComponent(LibraryComponent);
const lib = fixture.debugElement.componentInstance;
expect(lib).toBeTruthy();
});
});
<div
class="dropdown"
[ngClass]="{ open: open }"
tab-index="-1"
[class]="class"
#dropdown
>
<div class="dropdown__toggle" (click)="onTitleClick(dropdown)">
<span class="dropdown__title">{{ finalTitle() }}</span>
<span class="dropdown__icon icon-arrow-down"></span>
</div>
<div *ngIf="open" class="dropdown__menu">
<ul>
<li
*ngFor="let item of items; let ind = index"
class="dropdown__item"
[ngClass]="{ selected: selectedIndex === ind }"
(click)="onItemClick(dropdown, item, ind)"
>
<span class="dropdown__label">{{ item }}</span>
</li>
</ul>
</div>
</div>
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-dropdown',
templateUrl: './dropdown.component.html',
styleUrls: ['./dropdown.component.scss']
})
export class DropdownComponent implements OnInit {
@Input() items: Array<string>;
@Input() public selectedIndex: number = null;
@Input() public title = 'Select one';
@Input() public open = false;
@Input() public class = '';
@Output() pick = new EventEmitter();
constructor() { }
ngOnInit() {}
finalTitle () {
return typeof this.selectedIndex === 'number'
? this.items[this.selectedIndex]
: this.title;
}
onItemClick(dropdown, item, index) {
this._blur(dropdown);
this.selectedIndex = index;
this.open = false;
this.pick.emit({ item, index });
}
onTitleClick(dropdown) {
this._blur(dropdown);
this.open = !this.open;
}
_blur(dropdown) {
if (dropdown && dropdown.blur) { dropdown.blur(); }
}
}
最佳答案
更新以更清楚地回答您的 3 个问题
一)有很多方法可以在不创建新模块的情况下完成此操作。您可以按照 André 下面的建议将 DropdownComponent 简单地导入您的测试模块。我在这个答案的下面概述了另一种方法,它 stub DropdownComponent,只是为了测试 LibraryComponent。希望这能回答“如何做到这一点”的问题。
B) 我建议的 stub 不是一个模块——它甚至不是一个组件。没有必要将 stub 合并到整个应用程序中,它的唯一目的是测试 LibraryComponent。
C) 此 stub 的值仅用于测试 LibraryComponent,这就是为什么让它尽可能简单是个好主意。
这是在不将组件转换为模块的情况下让测试工作的一种方法。
stub 下拉组件:
下面是一种 stub 您尝试在 LibraryComponent 内部使用的 DropdownComponent 的方法。您在问题中详述的错误与您没有定义“app-dropdown”选择器这一事实直接相关,但您的 LibraryComponent 正试图绑定(bind)到它。假设您只想在 library.component.spec.ts 文件中测试 LibraryComponent,我建议将 DropdownComponent 功能 stub ,而不是将实际组件导入测试。我创建了一个 Stackblitz表明我的意思。
来自 Stackblitz,这是 library.component.spec.ts 文件中的一个片段:
@Component({
selector: 'app-dropdown',
template: `<h5>Dropdown</h5>`
})
class TestDropdownComponent {
@Input() items;
@Input() title;
@Output() pick = new EventEmitter<any>();
}
describe('LibraryComponent', () => {
let component: LibraryComponent;
let fixture: ComponentFixture<LibraryComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ RouterTestingModule ],
declarations: [
TestDropdownComponent,
LibraryComponent
]
}).compileComponents();
fixture = TestBed.createComponent(LibraryComponent);
}));
it('should create the component', () => {
const fixture = TestBed.createComponent(LibraryComponent);
const lib = fixture.debugElement.componentInstance;
expect(lib).toBeTruthy();
});
});
Note - If you want to reproduce the error you detail in your question within the Stackblitz, simply comment out the line for TestDropdownComponent in the declarations of the TestBed so it looks like so:
TestBed.configureTestingModule({
imports: [ RouterTestingModule ],
declarations: [
// TestDropdownComponent,
LibraryComponent
]
}).compileComponents();
And you will once again be testing just your component without a mock/stub of DropdownComponent to bind to.
关于 Angular Testing 错误 - 无法绑定(bind)到 'items',因为它不是 'app-dropdown' 的已知属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53345091/
我正在尝试让 Bootstrap 下拉菜单与我的 Jade 布局一起使用。但实际上,当我尝试在我的 Jade 文件中执行 $(".dropdown-toggle").dropdown 时出现此错误:
我正在使用 Semantic React UI's Dropdown ,并且我希望它在其父组件安装后立即获得焦点:用户应该能够立即搜索。 我尝试在父级的 render() 中使用 ref: (thi
我有一个脚本如下: var i = 0; function add_relation() { i = i + 1; var key = $('', {
我在 MVC 中有 2 个 DropDowns 并尝试使用 AngularJS。我的第一个 DropDown 填充了正确来自数据库的数据。当用户在第一个 DropDown 上进行选择时,第二个 Dro
我是一名开发新手,但我偶然发现了一个我无法解决的案例。我将 ASP.NET MVC 与 C# 以及一些 javascript(JQuery、JSON...)结合使用。 我要做的是根据在 other 中
在 Bootstrap 文档中,似乎有两种不同的方法来创建下拉列表: .dropdown .btn-group first如下: Dropdown ...
我确实在 kv 文件中定义了一个基本的自定义 DropDown。应用程序 GUI 非常简单,顶部有一个按钮栏,屏幕的其余部分有一个 TextInput。这是代码: dropdowntrialgui.p
在移动 View 中单击 .dropdown 菜单时,.dropdown 和 .dropdown-menu 之间有一个小空间. 如图所示 Question is it possible to remo
我正在尝试创建一个类似于 DataEntry 网格/表的结构,其中用户在单击按钮时追加新行。该行将包含文本框、下拉菜单、日历控件。所有这些都应该在客户端完成。到目前为止,我已经有了这个,正如你所看到的
我有一个带有使用 ul 和 li ( jsfiddle ) 的下拉列表的 jsfiddle。尝试将其转换为选择选项下拉列表时,我没有得到相同的选项 ([jsfiddle]) 2 .我猜这与我重命名某个
我正在使用@atlaskit/dropdown-menu (https://atlaskit.atlassian.com/packages/core/dropdown-menu)。我想在 Item 点
我在我的 angular 应用程序中使用 PrimeNG,我有 p-dropdown 的问题 问题 我为 country 和 caste_category 有两个下拉菜单,我只为 India 提供 c
我有一个表单 View ,在编辑模板中我有两个下拉菜单。 下拉 1 明确设置了允许值的列表。它也设置为自动回发。 下拉 2 是数据绑定(bind)到 objectdatasource,这个 objec
我有一个名为 Agency 的下拉菜单,其中包含 2 个选项: 文凭 PPS 如果选择 SPM,则不会出现下拉菜单。但是,如果选择 PPS,则会出现另外 2 个名为 Department 和 Offi
我是 Angular 的新手,所以这可能是一个非常简单的问题。我正在使用 ngx-select-dropdown (下拉控件)。页面上有两个下拉控件,当第一个下拉列表更改时,第二个下拉列表应更新下拉选
我有一个包含文本区域的下拉菜单。当在文本区域按下返回键时,我希望关闭下拉菜单。这是以下内容的作用: $(document).ready(function(){ $('#edit').keypres
我的页面中有这些SELECT Pending Confirmed Cancelled Refunded Shipped Paid Complete 还有这个 Pending Confirme
我有兴趣学习以智能、优雅的方式在整个站点中构建导航项,这些导航项具有胡萝卜,单击后会展开菜单项列表。 我希望动态构建菜单项(不一定全部使用 ajax)。但它们不应在页面上进行硬编码。 这似乎是像 TW
我有一个选择下拉菜单,一个是 Bootstrap 导航下拉菜单,而不是单击以打开 Bootstrap 导航下拉菜单我在鼠标悬停时更改了它但是当选择下拉菜单打开并且鼠标悬停在 Bootstrap 导航上
我对此很陌生,所以如果我的问题没有按应有的方式提出,我深表歉意。 基本上,我使用 jQuery 的目的是,当从第一个下拉框中选择名为“Apple”的字段时,第二个下拉框将只允许选择“Firm”字段,而
我是一名优秀的程序员,十分优秀!