您好SO社区和Angularians!
因此,我正在Angular 2中开发一个巨大的平台.我意识到Angular 2的许多外部库和依赖项正在迁移到新的Angular 4.很明显,给了我许多错误.
我可以分叉这些库并使用分叉版本并订阅主库开发,或者我可以升级到Angular 4我的项目.
要回答的问题是为了确定我是否值得迁移:
我发现了一些改进以确保与遗留的兼容性,如下所示:https://github.com/angular/angular/commit/e99d721
我是否必须通过我的整个应用程序并开始修复?
我的意思是,主要功能是否以这种方式重新设计,我将不得不审查其中的许多功能?
或者,是否有许多构建/核心不兼容性,这将使我几天占用修复编译错误/警告而不是开发?
我不是要求有人为我做研究,我问人们可能已经完成了这个过程,或者只是熟悉两个版本,以便给我一些经验提示,澄清等.
目前,我在这里做研究:
UPDATE
我刚刚迁移到Angular 4.@PierreDuc在他的回答中提供的链接是一个非常好的工具,可以在迁移过程中获得合适的指导.
我建议:
我还建议您提交当前项目,在dev存储库中创建一个新分支,然后继续在该分支中进行迁移.
一个问题,我遇到:
Input,Output并ContentChild会从错误的道路进口.
我的情况:
import { Component, OnInit, OnDestro } from '@angular/core';
import { Input, ContentChild } from "@angular/core/src/metadata/directives";
Run Code Online (Sandbox Code Playgroud)
解:
import { Component, OnInit, OnDestroy, Input, ContentChild } from '@angular/core';
Run Code Online (Sandbox Code Playgroud) 所以,我有一个使用这个模板动态呈现几个组件的组件:
<div [saJquiAccordion]="{active: group.value['collapsed']}" *ngFor="let group of filterGroupsTemplate | keysCheckDisplay;">
<div>
<h4>{{group.key | i18n}}</h4>
<form id="ibo-{{group.key}}" class="form-horizontal" autocomplete="off" style="overflow: initial">
<fieldset *ngFor="let field of group.value | keys">
<ng-container *ngComponentOutlet="fieldSets[field.value.template];
ngModuleFactory: smartadminFormsModule;"></ng-container>
</fieldset>
</form>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
问题是填充那些我从API调用中获取它的组件所需的数据:
this.getFiltersSubscription = this.getFilters().subscribe(
(filters) => {
this.filters = filters;
log.info('API CALL. getting filters');
// Sending data to fieldform components
this.iboService.updateIBOsRankList(filters['iboRank'].data);
this.iboService.updateIBOsNewsletterOptions(filters['iboNewsletter'].data);
this.iboService.updateIBOsTotalOrders(filters['iboTotalOrders'].data);
}
);
Run Code Online (Sandbox Code Playgroud)
因此,一旦我获得了数据,我就会触发我的组件订阅的服务Observable,然后他们将处理收集的数据.
问题:
如果在所有组件加载之前进行API调用,我将触发这些服务方法传递数据,但没有人会订阅这些Observable.
一种方法是:
首先加载数据,只有当我加载了数据时,我才会渲染模板,因此动态渲染所有这些组件,然后才会触发这些服务方法(Observables).
我不想为每个组件进行API调用,因为它可能像60个组件,我宁愿松散代码的抽象,但我喜欢做这样的事情:
// Listens to field's init and creates the …Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中多次这样做了.它很简单,它应该工作......但这次它没有.
我的问题:
我在组件A中调用服务中的方法,我的组件B已订阅但不响应也不接收任何内容.subscribe()没有触发!
导航elements.service.ts
@Injectable()
export class NavigationElementsService {
updateIBOsNavigation$: Observable<any>;
private updateIBOsNavigationSubject = new Subject<any>();
constructor() {
this.updateIBOsNavigation$ = this.updateIBOsNavigationSubject.asObservable();
}
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigationSubject.next(navigationData);
}
}
Run Code Online (Sandbox Code Playgroud)
IboDetailsGeneral 零件
export class IboDetailsGeneral implements OnInit, OnDestroy {
id: string;
private sub: any;
constructor(private route: ActivatedRoute, private iboService: IBOsService, private navigationService: NavigationElementsService) {
this.sub = this.route.params.subscribe(params => {
this.id = params['id'];
console.log('CALLING updateIBOsNavigation FUNCTION');
this.navigationService.updateIBOsNavigation(this.id);
});
}
ngOnInit() {
console.log('CALLING updateIBOsNavigation FUNCTION AGAIN');
this.navigationService.updateIBOsNavigation('test');
}
ngOnDestroy() {
this.sub.unsubscribe(); …Run Code Online (Sandbox Code Playgroud) 是否有一种简单的方法可以将真/假值显示为是/否?
我正在从数据库中检索包含以下内容的JSON:
[Object,Object,"WithCertification":true]
这是html:
凭证{{elem.WithCertification}}
显示这个:
认证真实
我希望它显示这个:
有认证是的
有没有办法不必去控制器将真/假改为是/否?
无论如何我需要改变它,任何建议?
谢谢.
我一直在尝试这个错误的几个解决方案,但没有找到任何成功的方法来克服这个:没有提供TemplateRef!
错误日志:
EXCEPTION:未捕获(在承诺中):错误:./FooterComponent类中的错误FooterComponent - 内联模板:15:20导致:没有TemplateRef的提供者!错误:./FooterComponent类中的错误FooterComponent - 内联模板:15:20导致:没有TemplateRef的提供程序!
未处理的Promise拒绝:./FooterComponent类中的错误FooterComponent - 内联模板:15:20导致:没有TemplateRef的提供者!; 区域:角; 任务:Promise.then; 值:
footer.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'sa-footer',
templateUrl: './footer.component.html'
})
export class FooterComponent implements OnInit {
constructor() {}
ngOnInit() {}
}
Run Code Online (Sandbox Code Playgroud)
footer.component.html
<div class="page-footer">
<div class="row">
<div class="col-xs-12 col-sm-6">
<span class="txt-color-white">myAPP © 2016</span>
</div>
<div class="col-xs-6 col-sm-6 text-right hidden-xs">
<div class="txt-color-white inline-block">
<i class="txt-color-blueLight hidden-mobile">Last account activity <i class="fa fa-clock-o"></i>
<strong>52 mins ago </strong> </i>
<div class="btn-group dropup" dropdown>
<button class="btn btn-xs …Run Code Online (Sandbox Code Playgroud) 我真的想解决这个错误,互联网上没有任何东西可以帮助我...
lr-categories.component.spec.ts:
export function main() {
describe('LrCategoriesComponent', () => {
let fixture: ComponentFixture<LrCategoriesComponent>;
let component: LrCategoriesComponent;
let de: DebugElement;
let glService: GeneralLedgeService;
let lrService: LrService;
let spy: jasmine.Spy;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
LrComponent,
LrMappingsComponent,
LrCategoriesComponent,
],
imports: [
CommonModule,
SharedModule,
LrRoutingModule,
AgGridModule.withComponents(
[
ButtonComponent,
ColumnHeaderComponent,
TypeaheadEditorComponent,
ButtonGroupComponent
]
)
],
providers: [
LrService,
{ provide: GeneralLedgeService, useClass: MockGeneralLedgeService },
CompleterService,
]
}).compileComponents().then(() => {
// initialization
fixture = TestBed.createComponent(LrCategoriesComponent);
component = fixture.componentInstance;
de = fixture.debugElement;
// Service …Run Code Online (Sandbox Code Playgroud) 理想情况下,我需要重新加载/重新呈现组件的模板,但如果有更好的方法,我会很乐意实现它.
期望的行为:
所以,我有一个菜单元素的组件.当(在另一个组件中)我单击一个IBO (某种'客户',每个说)被点击时,我需要添加(我正在使用*ngIf)菜单中的新选项,即IBO详细信息和子列表.
IBOsNavigationElement 组件(菜单组件):
@Component({
selector: '[ibos-navigation-element]',
template: `
<a href="#"><i class="fa fa-lg fa-fw fa-group"></i> <span
class="menu-item-parent">{{'IBOs' | i18n}}</span>
</a>
<ul>
<li routerLinkActive="active">
<a routerLink="/ibos/IBOsMain">{{'IBOs Main' | i18n}} {{id}}</a>
</li>
<li *ngIf="navigationList?.length > 0">
<a href="#">{{'IBO Details' | i18n}}</a>
<ul>
<li routerLinkActive="active" *ngFor="let navigatedIBO of navigationList">
<a href="#/ibos/IboDetails/{{navigatedIBO['id']}}">{{navigatedIBO['name']}}</a>
</li>
</ul>
</li>
</ul>
`
})
export class IBOsNavigationElement implements OnInit {
private navigationList = <any>[];
constructor(private navigationService: NavigationElementsService) {
this.navigationService.updateIBOsNavigation$.subscribe((navigationData) …Run Code Online (Sandbox Code Playgroud) 我需要验证datepicker的日期并限制年份(例如,避免15-05-9999).
这是我的HTML代码:
<p class="input-group">
<input type="text" name="raisedOnDate" class="form-control" ng-model="date" ng-disabled="!viewSearchEvent.raisedOnActive"
datepicker-popup="{{format}}" is-open="opened1" datepicker-options="dateOptions" date-validator required />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event,'on')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
<p ng-show="!searchEventsForm.$valid" style="color: red;">Date is invalid!</p>
<p ng-show="searchEventsForm.$valid" style="color: green;">Date is valid!</p>
Run Code Online (Sandbox Code Playgroud)
这是在里面<form name="searchEventsForm" role="form" class="form-horizontal" novalidate>.
我做了这个指令来验证日期类型:
app.directive('dateValidator', function() {
return {
require: 'ngModel',
link: function (scope, elem, attr, ngModel) {
function validate(value) {
var d = Date.parse(value);
// it is a date
if (isNaN(d)) { // d.valueOf() could also work …Run Code Online (Sandbox Code Playgroud) 我在Angular2项目中使用DataTables serverSide.
我正在尝试在进行更改后重新加载表,而这些更改我想通过AJAX将它们作为参数传递给POST.
问题是DataTables始终options从初始化获取对象,而不是具有新参数的更新版本.
所以,我需要的是,使用ajax.reload()传递一组新的参数.
这是我目前的职能:
filterData(tableParams) {
console.log('reloading DT. tableparams received are: ' + JSON.stringify(tableParams));
let element = $(this.el.nativeElement.children[0]);
let table = element.find('table.dataTable');
table.DataTable().ajax.reload();
}
Run Code Online (Sandbox Code Playgroud)
目前,你可以看到,我没有使用tableParams,这是因为我想展示我的功能的干净版本,我尝试了很多东西,但没有一个工作.
DataTables始终options使用初始参数获取初始对象.
这是我绝望的尝试之一:
filterData(tableParams) {
let element = $(this.el.nativeElement.children[0]);
let table = element.find('table.dataTable');
table.DataTable({
ajax: {
url: this.jsonApiService.buildURL('/test_getUsers.php'),
type: 'POST',
data: tableParams,
},
}).ajax.reload();
}
Run Code Online (Sandbox Code Playgroud)
一些帮助将非常感激.如果您需要有关如何创建DataTable的更多说明,或者有更多代码段告诉我.但我认为问题只是与ajax.reload()功能有关,能够发送更新的参数将解决问题.
非常感谢!
编辑1
这是我的init options对象:
let data = {
email: …Run Code Online (Sandbox Code Playgroud) 我正在创建一个表单,从后端获取字段。映射后,我有这样的东西:
genericFilters: {
iboId: {
'display': false,
'template': ''
},
iboCode: {
'display': true,
'template': 'text_input_iboCode',
/*'template': 'text/iboCode'*/
},
iboName: {
'display': true,
'template': 'text_input_iboName'
},
iboSurname: {
'display': true,
'template': 'text_input_iboSurname'
},
iboRank: {
'display': false,
'template': 'multiselect_iboRank',
/*'template': 'select/multi_iboRank',*/
},
iboEmail: {
'display': false,
'template': 'text_input_iboEmail'
},
iboNewsletter: {
'display': true,
'template': 'simple_select_iboNewsletter',
/*'template': 'select/simple_iboNewsletter',*/
},
};
Run Code Online (Sandbox Code Playgroud)
我的想法是在应用程序级别为表单字段创建每个字段类型(checkbox、multiselect、text、等)。radio并使用上面的映射JSON将某种字段类型应用于从后端接收的每个字段。
在我的示例中,该字段iboId应具有字段类型<text_input_iboCode>。
所以,在我看来,我不想有这样的事情:
<text_input_iboCode></text_input_iboCode>
<text_input_iboName></text_input_iboName>
<text_input_iboSurname></text_input_iboSurname>
Run Code Online (Sandbox Code Playgroud)
我实际上想让表单创建更抽象,如下所示: …
我不想在next()方法上做任何事情,我想处理error()和complete()。
这是我目前运行良好的解决方案:
this.myService.myServiceObservable(params)
.subscribe(
() => {
/**/
},
error => {
// Handling errors here
},
() => {
// Handling `complete()` here
}
);
Run Code Online (Sandbox Code Playgroud)
我觉得这:() => { /**/ }不是最优雅的解决方案。
任何人都知道如何获得相同的结果但不是那么难看?我错过了什么吗?
在测试具有共享服务的简单组件时,出现以下错误消息,我无法使其正常工作,我已经尝试了所有方法!
类型错误:无法读取未定义的属性“订阅”
lr.component.ts
export class LrComponent implements OnDestroy {
currentRouter: string;
private subscription: Subscription;
constructor(private lrService: LrService) {
this.subscription = this.lrService.lrNavigation$.subscribe(
(currentNav: string) => {
this.currentRouter = currentNav;
},
(error) => {
console.warn(error);
}
);
}
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
}
Run Code Online (Sandbox Code Playgroud)
lr.service.ts
@Injectable()
export class LrService {
// Observables for our components to subscribe to.
lrNavigation$: Observable<string>;
// Subjects to return data to subscribed components
private lrNavigationSubject = new Subject<string>();
constructor() {
this.lrNavigation$ = this.lrNavigationSubject.asObservable();
} …Run Code Online (Sandbox Code Playgroud) angular ×10
typescript ×5
javascript ×3
angular4 ×2
angularjs ×2
jasmine ×2
karma-runner ×2
ajax ×1
angular-cli ×1
angular-seed ×1
datatables ×1
datepicker ×1
ecmascript-6 ×1
migration ×1
observable ×1
rxjs ×1
validation ×1