在角度2中创建动态组件时,我发现此过程需要ViewContainerRef才能将新创建的组件添加到DOM.
Angular 2动态选项卡,用户单击所选组件 https://www.lucidchart.com/techblog/2016/07/19/building-angular-2-components-on-the-fly-a-dialog-box-example/
在将输入和输出传递给那些动态创建的组件时,我在上面的第二个链接中找到了答案:https: //codedump.io/share/kQakwDKNu0iG/1/passing-input-while-creating-angular-2-组件的动态使用-componentresolver
但是,如果我要创建一个名为shape.service的服务,其中包含使用bgColor等输入返回不同形状组件的函数,我不知道该服务如何在不指定DOM位置的情况下创建组件,以及容器组件如何接收这个返回的组件(可能是它的类型将是ComponentRef)来自服务并将其注入DOM容器组件指定.
例如,服务包含一个功能:
getCircle(bgColor:string): ComponentRef<Circle> {
let circleFactory = componentFactoryResolver.resolveComponentFactory(CircleComponent);
let circleCompRef = this.viewContainerRef.createComponent(circleFactory);
circleCompRef.instance.bgColor = bgColor;
return circleCompRef;
}
Run Code Online (Sandbox Code Playgroud)
第一个问题在这里提出,我如何ViewContainerRef在此期间指出无处?我导入viewContainerRef的原因是动态创建组件.
第二个问题是容器组件@Input从服务接收特定于输入的内容后,它将如何注入其DOM?
提前致谢!
更新: 我认为上面的问题不够具体.我遇到的情况是:
这意味着服务调用组件不知道这些componentRef将被注入的位置.简而言之,我需要可以随时随地注入的独立组件对象.
我已经好几次读过rumTimeCompiler解决方案,但我真的不知道它是如何工作的.与使用viewContainerRef创建组件相比,似乎有太多工作要做.如果我找不到其他解决方案,我会深入研究一下......
我试图将值从一个组件传递到另一个组件.
位置清单
<div uib-accordion-group class="panel-default" heading="{{location.name}}" ng-repeat="location in $ctrl.locations">
<p>This is from location list: {{location.id}}</p>
<bike-list locationId="{{location.id}}"></bike-list>
</div>
Run Code Online (Sandbox Code Playgroud)
输出:
这是来自位置列表:1
位置ID是:
自行车清单
自行车list.component.js
angular
.module('bikeList')
.component('bikeList', {
templateUrl: 'bike-list/bike-list.template.html',
controller: ['$rootScope', function ($rootScope) {
var self = this;
self.bikes = $rootScope.currentBikes;
}],
bindings: {
locationId: '<'
}
});
Run Code Online (Sandbox Code Playgroud)
自行车list.template.html
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>Location id is : {{$ctrl.locationId}}</p>
</body>
Run Code Online (Sandbox Code Playgroud)
输出:
位置ID是:
题
使用选择器成功。
<app-child1 (onVoted)="onVoted($event)"></app-child1>
Run Code Online (Sandbox Code Playgroud)
但是使用路由器会失败
<router-outlet (onVoted)="onVoted($event)"></router-outlet>
Run Code Online (Sandbox Code Playgroud)
我想从“路由器插座”上显示的组件接收一个值。
请告诉我我有什么方法。
应用程序?https://toparent.herokuapp.com/ src: https://github.com/kuniatsu/routerQuestion
<h1>
{{title}}
</h1>
<a href="c1">child1</a>
<router-outlet (onVoted)="onVoted($event)"></router-outlet><!--fail-->
<hr />
<app-child1 (onVoted)="onVoted($event)"></app-child1><!--success-->
Run Code Online (Sandbox Code Playgroud) 我有一个带有模板的组件,可以像这样有条件地显示:
@Component({
selector: "presentation",
template: "<template #tpl><!-- HTML --></template>"
})
export class Presentation implements AfterViewInit {
@ViewChild('tpl') template: TemplateRef<any>;
constructor(private view: ViewContainerRef) {}
ngAfterViewInit() {
this.view.createEmbeddedView(this.template);
}
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试编写测试,但一旦我打电话
it("should launch card in practice mode", () => {
fixture.detectChanges();
}
Run Code Online (Sandbox Code Playgroud)
我得到:
Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
尝试与@Output 事件发射器进行子级与父级通信,但这里不起作用的是子组件
import { Component, OnInit, Output, Input, EventEmitter } from '@angular/core';
@Component({
selector: 'app-emiter',
templateUrl: './emiter.component.html',
styleUrls: ['./emiter.component.css']
})
export class EmiterComponent implements OnInit {
@Output() emitor: EventEmitter<any>
constructor() { this.emitor = new EventEmitter()}
touchHere(){this.emitor.emit('Should Work');
console.log('<><><><>',this.emitor) // this comes empty
}
ngOnInit() {
}
}
Run Code Online (Sandbox Code Playgroud)
这是 html 模板
<p>
<button (click)=" touchHere()" class="btn btn-success btn-block">touch</button>
</p>
Run Code Online (Sandbox Code Playgroud)
touchHere 中的 console.log 即使我把它放在父组件中它也没有显示任何内容它也没有显示父组件
import { Component , OnInit} from '@angular/core';
// service I use for other stuff//
import { SenderService } …Run Code Online (Sandbox Code Playgroud) 我无法获得我的自定义元素的 nativeElement 的引用。我有一个这样的模板:
<div #testone>
<my-feature-cmp><my-feature-cmp>
<my-feature-cmp><my-feature-cmp>
<my-feature-cmp><my-feature-cmp>
<div>
Run Code Online (Sandbox Code Playgroud)
用于访问的代码:@ViewChild('testone') el: ElementRef;
当我这样做时,我得到了元素引用 -> console.log(this.el.nativeElement)
第二种模板
<my-feature-cmp></my-feature-cmp>
<my-feature-cmp></my-feature-cmp>
<my-feature-cmp></my-feature-cmp>
Run Code Online (Sandbox Code Playgroud)
用于访问的代码:
@ViewChildren(MyFeatureCmp) el: MyFeatureCmp;
Run Code Online (Sandbox Code Playgroud)
执行此操作时出现本机元素错误 ->
console.log(this.el.nativeElement)
Run Code Online (Sandbox Code Playgroud)
当我这样做时,我得到了类引用并且没有 nativeElement ->
console.log(this.el)
console.log(this.el.toArray())
Run Code Online (Sandbox Code Playgroud)
问题是如果我想更改标签属性,如何访问自定义组件的本机元素。其次,无论我以何种方式访问它们,如果我手动更改自定义组件的属性,它是否也会在更改后被检测为更改?
我正在研究组件,我想实现一个功能,该功能着眼于ng-content内部的第一个输入元素。
因此,我严格按照以下模板代码尝试此操作,并尝试使用ViewChildren和ContentChildren。
@Component({
selector: '[my-component]', // tslint:disable-line
template: `<div class="my-container">
<ng-content></ng-content>
</div>`
})
export class MyComponent implements AfterViewInit, OnDestroy {
@ViewChildren('input') vc;
@ContentChildren('input', {descendants: true}) cc;
ngAfterViewInit() {
//Nothing in either QueryList ???
console.log(this.vc, this.cc);
}
focus () {
//Nothing in either QueryList ???
this.vc.first.nativeElement.focus();
}
}
Run Code Online (Sandbox Code Playgroud)
在模板/页面中使用组件时,它看起来大致如下:
<div my-component>
<div class="field"><input></div>
<div class="field"><input></div>
<div class="field"><input></div>
<div class="field"><input></div>
<div class="field"><input></div>
</div>
Run Code Online (Sandbox Code Playgroud)
再说一遍,我想获得的是所有出现在内容中的输入元素,它们也可以埋在div和wrapper中。看来ContentChildren应该是正确的,但它没有返回任何元素。即QueryList.results为空。
我在做错什么或如何在内容区域内获取输入?
我有一个按钮组件,它接受承诺并禁用按钮,直到承诺解决为止,并且我想为此功能编写单元测试。
我的按钮组件有一个承诺的输入
/**
* A single promise that triggers the busy state until it resolves
*/
@Input()
public promise: Promise<any>;
Run Code Online (Sandbox Code Playgroud)
在ngOnChanges内部,我听了承诺
/**
* Enable button busy state until promise resolves
*/
if (changes && changes.promise && changes.promise.currentValue) {
this.busyUntilPromiseResolves(changes.promise.currentValue);
}
Run Code Online (Sandbox Code Playgroud)
然后,我存储了一个有效的promise数组,以便可以传递多个promise
/**
* Add a promise that will keep the button in a busy state until it resolves
* @param activityProimise
*/
private busyUntilPromiseResolves(activityProimise) {
this.activityPromises.push(activityProimise);
activityProimise.then(() => {
this.activityPromises.splice(this.activityPromises.indexOf(activityProimise), 1);
});
}
Run Code Online (Sandbox Code Playgroud)
然后最后在我的模板中,如果数组中有任何promise,我将禁用按钮。
[disabled]="activityPromises.length > 0"
Run Code Online (Sandbox Code Playgroud)
unit-testing promise angular-components angular angular-unit-test
如何访问子元素(此处<img>)的@ViewChild()在角2+没有明确的声明?
在template.html中
<div #parent>
<!-- There can be anything than <img> -->
<img src="http://localhost/123.jpg" alt="">
</div>
Run Code Online (Sandbox Code Playgroud)
在component.ts中
@ViewChild('parent') parent;
public getFirstChild() {
this.firstChild = this.parent.? //
}
Run Code Online (Sandbox Code Playgroud)
目的是能够创建使用以下内容的通用组件:
<div #parent>
<ng-content></ng-content>
</div>
Run Code Online (Sandbox Code Playgroud)
因此,#parent无需显式声明即可访问需要的子元素。
我正在创建我的第一个Angular应用,并且在开发模式控制台中遇到以下错误:
错误错误:“找不到具有未指定名称属性的控件”
错误错误:“找不到具有路径的控件:'项目->名称'”
错误错误:“找不到路径为:'项目->高度'的控件”
我已经读了几个SO答案(例如this,this this和this),但是我无法指出我做错了什么,我对Angular的经验不足也无济于事。
这是我的组件打字稿代码:
import {Component, OnInit} from '@angular/core';
import {FormArray, FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';
@Component({
selector: 'app-pack-input',
templateUrl: './pack-input.component.html',
styleUrls: ['./pack-input.component.css']
})
export class PackInputComponent implements OnInit {
public boxForm: FormGroup;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.boxForm = this.formBuilder.group({
items: this.formBuilder.array([this.createBox()])
});
}
createBox(): FormGroup {
return this.formBuilder.group({
name: ['', [Validators.required, Validators.minLength(3)]],
height: ['', [Validators.required, Validators.minLength(3)]],
width: ['', [Validators.required, Validators.minLength(3)]],
length: ['', [Validators.required, Validators.minLength(3)]],
weight: ['', …Run Code Online (Sandbox Code Playgroud) typescript angular-components angular angular-forms angular-formbuilder
angular ×9
javascript ×2
viewchild ×2
angularjs ×1
data-binding ×1
html ×1
promise ×1
typescript ×1
unit-testing ×1