我正在使用this guide将我的应用从Ionic 2.0.0-beta.20
升级到Ionic 2.0.0-rc.3
。
我的代码在Ionic 2.0.0-beta.20
版本中工作,但自从升级并遵循指南中的所有步骤后,当我ionic serve
时,我遇到了很多错误(见下文)。
问题
我的问题是,我在做什么根本就是错误的,如果我在一个地方纠正它应该有效,或者我应该单独看每个错误?升级时有没有其他人遇到过这类问题?
代码
chats.ts
import { Component } from '@angular/core';
import { NavController, NavParams, ViewController, AlertController, Events } from 'ionic-angular';
import { MeteorComponent } from 'angular2-meteor';
import { CalendarPipe } from 'angular2-moment';
import { Mongo } from 'meteor/mongo';
import { Chat, Message } from 'api/models';
import { Chats, Messages } from 'api/collections';
import { MessagesPage } from '../messages/messages';
import { UtilityService } from '../utils/utilityService';
import { PersonModel } from '../model/personModel';
import { JobModel } from '../model/jobModel';
import { LoginPage } from '../login/login';
import { JobService } from '../service/jobService';
import { PersonService } from '../service/personService';
import { ChatsStorageService } from '../chats/chatsStorageService';
@Component({
templateUrl: 'chats.html'
})
export class ChatsPage extends MeteorComponent {
public chats: Mongo.Cursor<Chat>;
public localChatCollection: Mongo.Collection<Chat> = new Mongo.Collection<Chat>(null);
public localChatCursor: Mongo.Cursor<Chat>;
public utilityService: UtilityService = null;
public jobService: JobService = null;
public personService: PersonService = null;
public personModelLoggedIn: PersonModel = null;
public personModels: PersonModel[] = [];
public jobModels: JobModel[] = [];
public jobModelsForSender: JobModel[] = [];
public personModel: PersonModel = null;
public jobModel: JobModel = null;
public senderId: string = null;
public events: Events = null;
public chatsLoading: boolean = true;
public chatsStorageService: ChatsStorageService = null;
constructor(public navCtrl: NavController, public navParams: NavParams, public viewCtrl: ViewController, public alertCtrl: AlertController, utilityService: UtilityService, jobService: JobService, personService: PersonService, events: Events, chatsStorageService: ChatsStorageService) {
super();
this.events = events;
this.utilityService = utilityService;
this.jobService = jobService;
this.personService = personService;
this.chatsStorageService = chatsStorageService;
this.setParams();
this.subscribeEvents();
}
public subscribeEvents(): void {
let observedPromise: Promise<string> = this.utilityService.getLocalStrorage('this.messages.subscribe');
observedPromise.then((observed: string) => {
if (!observed || observed != 'true') {
this.utilityService.setLocalStrorage('this.messages.subscribe', 'true');
this.events.subscribe('messages:update', (data) => {
console.log('subscribeEvents: messages:update loadChats()');
this.loadLocal(null);
this.loadServer(false);
});
}
});
}
public setParams(): void {
this.utilityService.setLocalStrorage('chats.addingNewChat', 'false');
this.jobModel = this.navParams.get('jobModel');
this.personModel = this.navParams.get('personModel');
let promise: Promise<string> = this.utilityService.getLoggedInPerson();
promise.then((data) => {
let personModelLoggedIn: PersonModel = JSON.parse(data);
if (personModelLoggedIn) {
this.personModelLoggedIn = personModelLoggedIn;
this.senderId = 'P' + this.personModelLoggedIn.id;
let promiseJobsForPerson: Promise<JobModel[]> = this.jobService.getJobsByPerson(personModelLoggedIn.id);
promiseJobsForPerson.then((data) => {
this.jobModelsForSender = data;
this.loadChats();
});
} else {
this.navCtrl.push(LoginPage, {
fromChats: true
});
}
});
}
findChat(senderId: string, receiverId: string): Chat {
const chat: Chat = Chats.findOne({
memberIds: { $all: [senderId, receiverId] }
});
return chat;
}
showMessages(chat: Chat): void {
console.log('showMessages: ', chat);
let data = {
chat: chat,
chatsStorageService: this.chatsStorageService
}
this.navCtrl.push(MessagesPage, data);
}
removeChat(chat): void {
console.log('removeChat: ', chat);
this.call('removeChat', this.senderId, chat._id);
// this.localChatCollection.remove(chat);
// this.localChatCursor = this.localChatCollection.find();
let data = {
chat: chat
}
this.events.publish('remove:chat', data);
console.log('chatsStorageService.removeChat: ', chat._id);
this.chatsStorageService.removeChat(chat);
//this.loadLocal(null);
this.loadServer(false);
this.navCtrl.pop();
}
public loadChats(): void {
this.loadLocal(null);
this.loadServer(true);
}
public loadLocal(lastMessage: Message): void {
Promise.all([this.chatsStorageService.refreshChats(), this.chatsStorageService.refreshMessages()]).then((data: any) => {
let promiseLocalChats: Promise<Mongo.Collection<Chat>> = null;
if (lastMessage) {
promiseLocalChats = this.findLocalChats(lastMessage);
} else {
promiseLocalChats = this.findLocalChatsWithLastMessageForChat();
}
promiseLocalChats.then((chatData: Mongo.Collection<Chat>) => {
chatData.find().forEach((chat: Chat) => {
this.addOrUpdateLocalChat(chat);
});
this.sortLocalChats();
});
});
}
public sortLocalChats(): void {
this.localChatCursor = this.localChatCollection.find({}, { sort: { lastMessageCreatedAt: -1 } });
// this.localChatCursor.fetch().forEach((chat: Chat) => {
// });
this.chatsLoading = false;
console.log('==> loaded sorted local chats: ' + this.localChatCollection.find().count());
}
public addOrUpdateLocalChat(chat: Chat): void {
let foundChat: Chat = this.localChatCollection.findOne({ _id: chat._id });
if (foundChat && foundChat._id === chat._id) {
let updatedChat: Chat = this.localChatCollection.update(
{ _id: chat._id },
{ $set: { lastMessageCreatedAt: chat.lastMessageCreatedAt, lastMessage: chat.lastMessage } }
);
if (updatedChat) {
this.chatsStorageService.updateChat(updatedChat);
}
} else if (!foundChat) {
let returnVal: string = this.localChatCollection.insert(chat);
}
}
public loadServer(showMessage: boolean): void {
let promiseChats: Promise<Mongo.Collection<Chat>> = this.findChats();
promiseChats.then((data: Mongo.Collection<Chat>) => {
const recieverIds: string[] = this.chats
.map(({memberIds}) => memberIds)
.reduce((result, memberIds) => result.concat(memberIds), [])
.concat(this.senderId);
this.getMatchingData(recieverIds, showMessage);
});
}
public getMatchingData(recieverIds: string[], showMessage: boolean): void {
if (this.jobModel) {
if (recieverIds.indexOf('J' + this.jobModel.id) < 0) {
recieverIds.push('J' + this.jobModel.id);
}
}
if (this.personModel) {
if (recieverIds.indexOf('P' + this.personModel.id) < 0) {
recieverIds.push('P' + this.personModel.id);
}
}
recieverIds = this.removeDuplicates(recieverIds);
let jobIds: string = '';
let personIds: string = '';
for (let i = 0; i < recieverIds.length; i++) {
if (recieverIds[i] && recieverIds[i].substring(0, 1) == 'J') {
jobIds += recieverIds[i].substring(1, recieverIds[i].length);
jobIds += ',';
} else if (recieverIds[i] && recieverIds[i].substring(0, 1) == 'P') {
personIds += recieverIds[i].substring(1, recieverIds[i].length);
personIds += ',';
}
}
jobIds = jobIds.substring(0, jobIds.length - 1);
personIds = personIds.substring(0, personIds.length - 1);
let promisePersons: Promise<PersonModel[]> = this.personService.getPersons(personIds);
promisePersons.then((personModels: PersonModel[]) => {
for (var index = 0; index < personModels.length; index++) {
this.personModels.push(personModels[index]);
}
let promiseJobs: Promise<JobModel[]> = this.jobService.getJobs(jobIds);
promiseJobs.then((jobModels: JobModel[]) => {
for (var index = 0; index < jobModels.length; index++) {
this.jobModels.push(jobModels[index]);
}
if ((this.jobModels && this.jobModels.length > 0) || (this.personModels && this.personModels.length > 0)) {
let promise: Promise<Mongo.Collection<Chat>> = this.findChats();
promise.then((data: Mongo.Collection<Chat>) => {
data.find().forEach((chat: Chat) => {
this.addOrUpdateLocalChat(chat);
});
this.sortLocalChats();
if (showMessage) {
this.observeChats();
this.addNewChatAndShowMessage(null);
}
this.chatsLoading = false;
});
}
});
});
}
public observeChats(): void {
let observedPromise: Promise<string> = this.utilityService.getLocalStrorage('this.chats.observe');
observedPromise.then((observed: string) => {
if (!observed || observed != 'true') {
this.utilityService.setLocalStrorage('this.chats.observe', 'true');
this.chats.observe({
added: (chat) => this.chatAdded(chat),
changed: (newChat, oldChat) => this.disposeChat(newChat, oldChat),
removed: (chat) => this.disposeChat(null, chat)
});
}
});
}
public disposeChat(newChat: Chat, oldChat: Chat): void {
if (oldChat.receiverComp) {
oldChat.receiverComp.stop();
}
if (oldChat.lastMessageComp) {
oldChat.lastMessageComp.stop();
}
if (newChat && newChat != null && oldChat && oldChat != null && newChat._id === oldChat._id) {
if ((newChat.lastMessage && oldChat.lastMessage && newChat.lastMessage._id != oldChat.lastMessage._id) || (newChat.lastMessage && oldChat.lastMessage && newChat.lastMessage.readByReceiver != oldChat.lastMessage.readByReceiver)) {
let data = {
chat: newChat
}
console.log('disposeChat', newChat, oldChat);
this.events.publish('messages:update', data);
}
}
}
public chatAdded(chat: Chat) {
let observedPromise: Promise<string> = this.utilityService.getLocalStrorage('chats.addingNewChat');
observedPromise.then((addingNewChat: string) => {
if (addingNewChat && addingNewChat === 'true') {
console.log('chatAdded: ', chat, addingNewChat);
this.addNewChatAndShowMessage(chat);
}
});
}
public addNewChatAndShowMessage(chat: Chat) {
this.utilityService.setLocalStrorage('chats.addingNewChat', 'true');
if (this.jobModel) {
let jobId: string = 'J' + this.jobModel.id;
if (!chat || chat === null) {
chat = this.findChatAgain(this.senderId, jobId);
}
if (!chat || chat === null) {
this.addChat(jobId).then(() => {
// this.addNewChatAndShowMessage();
});
} else {
chat = this.transformChat(chat);
this.utilityService.setLocalStrorage('chats.addingNewChat', 'false');
this.showMessages(chat);
}
} else if (this.personModel) {
let personId: string = 'P' + this.personModel.id;
if (!chat || chat === null) {
chat = this.findChatAgain(this.senderId, personId);
}
if (!chat || chat === null) {
this.addChat(personId).then(() => {
// this.addNewChatAndShowMessage();
});
} else {
chat = this.transformChat(chat);
this.utilityService.setLocalStrorage('chats.addingNewChat', 'false');
this.showMessages(chat);
}
}
}
public findChatAgain(senderId: string, preJobId: string): Chat {
let chat: Chat = this.findChat(this.senderId, preJobId);
return chat;
}
public addChat(userId: string): Promise<any> {
return this.call('addChat', this.senderId, userId, (e: Error) => {
this.viewCtrl.dismiss().then(() => {
if (e) {
console.log('Error adding chat', e, userId);
return this.doAlert(e);
}
});
});
}
public transformChat(chat): Chat {
try {
const receiverId = chat.memberIds.find(memberId => memberId != this.senderId);
let profileName: string = null;
let profileSubTitle: string = null;
let profilePicture: string = null;
for (let i = 0; i < this.jobModels.length; i++) {
if (receiverId == 'J' + this.jobModels[i].id) {
profileName = this.jobModels[i].person.firstName + ' ' + this.jobModels[i].person.lastName;
profileSubTitle = this.jobModels[i].jobTitle;
if (this.jobModels[i].avatar && this.jobModels[i].avatar != null) {
profilePicture = decodeURIComponent(window.atob(this.jobModels[i].avatar));
}
}
}
for (let i = 0; i < this.personModels.length; i++) {
if (receiverId == 'P' + this.personModels[i].id) {
if (!profileName || profileName == null) {
profileName = this.personModels[i].firstName + ' ' + this.personModels[i].lastName;
}
if ((!profilePicture || profilePicture == null) && this.personModels[i].avatar && this.personModels[i].avatar != null) {
profilePicture = decodeURIComponent(window.atob(this.personModels[i].avatar));
}
}
}
if (profileName && profileName != null) {
chat.title = profileName;
}
if (profileSubTitle && profileSubTitle != null) {
chat.subTitle = profileSubTitle;
}
if (profilePicture && profilePicture != null) {
chat.picture = profilePicture;
}
let lastMessage: Message = this.findLastMessage(chat);
if (lastMessage) {
chat.lastMessage = lastMessage;
chat.lastMessageCreatedAt = lastMessage.createdAt;
}
} catch (e) {
console.log('error in transformChat: ' + e.message);
}
return chat;
}
public findLastMessage(chat: Chat): Message {
return Messages.findOne({
chatId: chat._id
}, {
sort: { createdAt: -1 }
});
}
public findLocalChats(lastMessage: Message): Promise<Mongo.Collection<Chat>> {
let promise: Promise<Mongo.Collection<Chat>> = new Promise<Mongo.Collection<Chat>>(resolve => {
let localChatCollection: Mongo.Collection<Chat> = new Mongo.Collection<Chat>(null);
for (let i: number = 0; i < this.chatsStorageService.chats.length; i++) {
let chat: Chat = this.chatsStorageService.chats[i];
if (lastMessage && lastMessage != null && lastMessage.chatId === chat._id) {
chat.lastMessage = lastMessage;
chat.lastMessageCreatedAt = lastMessage.createdAt;
localChatCollection.insert(chat);
}
}
resolve(localChatCollection);
});
return promise;
}
public findLocalChatsWithLastMessageForChat(): Promise<Mongo.Collection<Chat>> {
let promise: Promise<Mongo.Collection<Chat>> = new Promise<Mongo.Collection<Chat>>(resolve => {
let localChatCollection: Mongo.Collection<Chat> = new Mongo.Collection<Chat>(null);
let promises: Array<Promise<Mongo.Collection<Chat>>> = [];
for (let i: number = 0; i < this.chatsStorageService.chats.length; i++) {
let chat: Chat = this.chatsStorageService.chats[i];
let findLastMessageForChatPromise: Promise<Message> = this.chatsStorageService.findLastMessageForChat(chat);
promises.push(findLastMessageForChatPromise);
findLastMessageForChatPromise.then(function (_chat, data) {
let message: Message = data;
_chat.lastMessage = message;
_chat.lastMessageCreatedAt = message.createdAt;
localChatCollection.insert(_chat);
}.bind(null, chat));
};
Promise.all(promises).then(function () { resolve(localChatCollection); });
});
return promise;
}
public showUnread(chat: Chat): boolean {
if (chat && chat.lastMessage) {
if (chat.lastMessage.readByReceiver === false || chat.lastMessage.readByReceiver + '' === 'false') {
if (this.senderId != chat.lastMessage.senderId) {
return true;
}
}
}
return false;
}
public findChats(): Promise<Mongo.Collection<Chat>> {
let promise: Promise<Mongo.Collection<Chat>> = new Promise<Mongo.Collection<Chat>>(resolve => {
let registeredIds: String[] = [this.senderId];
for (let i = 0; i < this.jobModelsForSender.length; i++) {
registeredIds.push('J' + this.jobModelsForSender[i].id);
}
this.subscribe('chats', this.senderId, registeredIds, () => {
let chats: Mongo.Cursor<Chat> = Chats.find(
{ memberIds: { $in: registeredIds } },
{
sort: { lastMessageCreatedAt: -1 },
transform: this.transformChat.bind(this),
fields: { memberIds: 1, lastMessageCreatedAt: 1 }
}
);
this.chats = chats;
console.log('==> loaded server chats: ' + this.chats.count());
let localChatCollection: Mongo.Collection<Chat> = new Mongo.Collection<Chat>(null);
chats.forEach((chat: Chat) => {
localChatCollection.insert(chat);
});
resolve(localChatCollection);
});
});
return promise;
}
public doAlert(e: Error) {
console.error(e);
let alert = this.alertCtrl.create({
title: 'Oops!',
subTitle: e.message,
buttons: ['OK']
});
alert.present();
}
public removeDuplicates(arr: string[]): string[] {
var unique: string[] = arr.filter(function (elem, index, self) {
return index == self.indexOf(elem);
})
return unique;
}
}
错误
Typescript Error
Type 'any' is not a constructor function type.
E:/Development/IDE/ionic-apps/theWhoZoo/src/pages/chats/chats.ts
})
export class ChatsPage extends MeteorComponent {
public chats: Mongo.Cursor<Chat>;
Typescript Error
Module ''*'' has no exported member 'Cursor'.
E:/Development/IDE/ionic-apps/theWhoZoo/src/pages/chats/chats.ts
export class ChatsPage extends MeteorComponent {
public chats: Mongo.Cursor<Chat>;
public localChatCollection: Mongo.Collection<Chat> = new Mongo.Collection<Chat>(null);
Typescript Error
Module ''*'' has no exported member 'Collection'.
E:/Development/IDE/ionic-apps/theWhoZoo/src/pages/chats/chats.ts
public chats: Mongo.Cursor<Chat>;
public localChatCollection: Mongo.Collection<Chat> = new Mongo.Collection<Chat>(null);
public localChatCursor: Mongo.Cursor<Chat>;
Typescript Error
Untyped function calls may not accept type arguments.
E:/Development/IDE/ionic-apps/theWhoZoo/src/pages/chats/chats.ts
public chats: Mongo.Cursor<Chat>;
public localChatCollection: Mongo.Collection<Chat> = new Mongo.Collection<Chat>(null);
public localChatCursor: Mongo.Cursor<Chat>;
Typescript Error
Module ''*'' has no exported member 'Cursor'.
E:/Development/IDE/ionic-apps/theWhoZoo/src/pages/chats/chats.ts
public localChatCollection: Mongo.Collection<Chat> = new Mongo.Collection<Chat>(null);
public localChatCursor: Mongo.Cursor<Chat>;
public utilityService: UtilityService = null;
Typescript Error
Cannot find name 'Chat'.
E:/Development/IDE/ionic-apps/theWhoZoo/src/pages/chats/chats.ts
findChat(senderId: string, receiverId: string): Chat {
const chat: Chat = Chats.findOne({
Typescript Error
Cannot find name 'Chat'.
E:/Development/IDE/ionic-apps/theWhoZoo/src/pages/chats/chats.ts
findChat(senderId: string, receiverId: string): Chat {
const chat: Chat = Chats.findOne({
memberIds: { $all: [senderId, receiverId] }
Typescript Error
Cannot find name 'Chat'.
E:/Development/IDE/ionic-apps/theWhoZoo/src/pages/chats/chats.ts
showMessages(chat: Chat): void {
console.log('showMessages: ', chat);
Typescript Error
Property 'call' does not exist on type 'ChatsPage'.
E:/Development/IDE/ionic-apps/theWhoZoo/src/pages/chats/chats.ts
console.log('removeChat: ', chat);
this.call('removeChat', this.senderId, chat._id);
// this.localChatCollection.remove(chat);
...
更新
在我的应用中,我使用基于this的Meteror Chat App。因此,我有一个带有Ionic 2.0.0-beta.20
版本的自定义webpack。我目前没有使用Ionic 2.0.0-rc.3
版本。
可以/应该将它添加到新版本吗?
webpack.config.js
var camelCase = require('lodash.camelcase');
var upperFirst = require('lodash.upperfirst');
var webpack = require('webpack');
var isRelease = process.argv.indexOf('--release') > -1;
var config = module.exports = {
entry: './app/app.ts',
output: {
path: __dirname + '/www/build/js',
filename: 'app.bundle.js'
},
watch: true,
externals: [
'cordova',
resolveExternals
],
resolve: {
extensions: ['', '.webpack.js', '.web.js', '.ts', '.js'],
alias: {
api: __dirname + '/api/server'
}
},
module: {
loaders: [
{ test: /\.ts$/, loader: 'ts-loader' }
]
},
devtool: 'source-map'
};
if (isRelease) {
config.plugins = [
new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false }
})
];
}
function resolveExternals(context, request, callback) {
return meteorPack(request, callback) ||
cordovaPlugin(request, callback) ||
callback();
}
function cordovaPlugin(request, callback) {
var match = request.match(/^cordova\/(.+)$/);
var plugin = match && match[1];
if (plugin) {
plugin = camelCase(plugin);
plugin = upperFirst(plugin);
callback(null, 'window.cordova && cordova.plugins && cordova.plugins.' + plugin);
return true;
}
}
function meteorPack(request, callback) {
var match = request.match(/^meteor\/(.+)$/);
var pack = match && match[1];
if (pack) {
callback(null, 'window.Package && Package["' + pack + '"]');
return true;
}
}